thread_proxy.cc revision f2477e01787aa58f445919b809d89e252beef54f
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),
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      weak_factory_(this) {
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ThreadProxy");
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(this->layer_tree_host());
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ThreadProxy::~ThreadProxy() {
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::~ThreadProxy");
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!started_);
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ThreadProxy::CompositeAndReadback(void* pixels, gfx::Rect rect) {
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::CompositeAndReadback");
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(layer_tree_host());
132ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
133ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (defer_commits_) {
134ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    TRACE_EVENT0("cc", "CompositeAndReadback_DeferCommit");
135ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return false;
136ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!layer_tree_host()->InitializeOutputSurfaceIfNeeded()) {
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "CompositeAndReadback_EarlyOut_LR_Uninitialized");
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Perform a synchronous commit with an associated readback.
14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ReadbackRequest request;
14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request.rect = rect;
14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request.pixels = pixels;
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
1491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    CompletionEvent begin_main_frame_sent_completion;
15058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    Proxy::ImplThreadTaskRunner()
15158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        ->PostTask(FROM_HERE,
15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                   base::Bind(&ThreadProxy::ForceCommitForReadbackOnImplThread,
15358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              impl_thread_weak_ptr_,
1541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                              &begin_main_frame_sent_completion,
15558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              &request));
1561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    begin_main_frame_sent_completion.Wait();
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
158558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  in_composite_and_readback_ = true;
16058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // This is the forced commit.
1611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Note: The Impl thread also queues a separate BeginMainFrame on the
16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // main thread, which will be called after this CompositeAndReadback
16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // completes, to replace the forced commit.
1641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  BeginMainFrame(scoped_ptr<BeginMainFrameAndCommitState>());
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  in_composite_and_readback_ = false;
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
167558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Composite and readback requires a second commit to undo any changes
168558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // that it made.
169558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  can_cancel_commit_ = false;
170558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
17158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request.completion.Wait();
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return request.success;
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void ThreadProxy::ForceCommitForReadbackOnImplThread(
1761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    CompletionEvent* begin_main_frame_sent_completion,
17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ReadbackRequest* request) {
17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ForceCommitForReadbackOnImplThread");
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(IsImplThread());
1801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(!begin_main_frame_sent_completion_event_on_impl_thread_);
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!readback_request_on_impl_thread_);
18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_tree_host_impl_) {
1841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    begin_main_frame_sent_completion->Signal();
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    request->success = false;
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    request->completion.Signal();
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  readback_request_on_impl_thread_ = request;
19158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
19258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scheduler_on_impl_thread_->SetNeedsForcedCommitForReadback();
19358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (scheduler_on_impl_thread_->CommitPending()) {
1941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    begin_main_frame_sent_completion->Signal();
19558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
19658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
19758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  begin_main_frame_sent_completion_event_on_impl_thread_ =
1991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      begin_main_frame_sent_completion;
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::FinishAllRendering() {
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(Proxy::IsMainThread());
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!defer_commits_);
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make sure all GL drawing is finished on the impl thread.
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DebugScopedSetMainThreadBlocked main_thread_blocked(this);
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CompletionEvent completion;
209eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ThreadProxy::FinishAllRenderingOnImplThread,
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 impl_thread_weak_ptr_,
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 &completion));
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion.Wait();
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ThreadProxy::IsStarted() const {
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(Proxy::IsMainThread());
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return started_;
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ThreadProxy::SetLayerTreeHostClientReady() {
223b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetLayerTreeHostClientReady");
224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(&ThreadProxy::SetLayerTreeHostClientReadyOnImplThread,
227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 impl_thread_weak_ptr_));
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
230b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ThreadProxy::SetLayerTreeHostClientReadyOnImplThread() {
231b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetLayerTreeHostClientReadyOnImplThread");
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scheduler_on_impl_thread_->SetCanStart();
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SetVisible(bool visible) {
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetVisible");
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DebugScopedSetMainThreadBlocked main_thread_blocked(this);
238424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CompletionEvent completion;
240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(&ThreadProxy::SetVisibleOnImplThread,
243eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 impl_thread_weak_ptr_,
244eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 &completion,
245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 visible));
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion.Wait();
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SetVisibleOnImplThread(CompletionEvent* completion,
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         bool visible) {
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetVisibleOnImplThread");
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_impl_->SetVisible(visible);
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->SetVisible(visible);
254424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  UpdateBackgroundAnimateTicking();
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion->Signal();
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
258424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void ThreadProxy::UpdateBackgroundAnimateTicking() {
259424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  layer_tree_host_impl_->UpdateBackgroundAnimateTicking(
260424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      !scheduler_on_impl_thread_->WillDrawIfNeeded() &&
261424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      layer_tree_host_impl_->active_tree()->root_layer());
262424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
263424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::DoCreateAndInitializeOutputSurface() {
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::DoCreateAndInitializeOutputSurface");
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<OutputSurface> output_surface = first_output_surface_.Pass();
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!output_surface)
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    output_surface = layer_tree_host()->CreateOutputSurface();
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RendererCapabilities capabilities;
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool success = !!output_surface;
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!success) {
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    OnOutputSurfaceInitializeAttempted(false, capabilities);
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<ContextProvider> offscreen_context_provider;
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (created_offscreen_context_provider_) {
2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    offscreen_context_provider =
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        layer_tree_host()->client()->OffscreenContextProvider();
283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    success = !!offscreen_context_provider.get();
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!success) {
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      OnOutputSurfaceInitializeAttempted(false, capabilities);
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return;
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  success = false;
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  {
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Make a blocking call to InitializeOutputSurfaceOnImplThread. The results
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // of that call are pushed into the success and capabilities local
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // variables.
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CompletionEvent completion;
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&ThreadProxy::InitializeOutputSurfaceOnImplThread,
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   impl_thread_weak_ptr_,
302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   &completion,
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   base::Passed(&output_surface),
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   offscreen_context_provider,
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   &success,
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   &capabilities));
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    completion.Wait();
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  OnOutputSurfaceInitializeAttempted(success, capabilities);
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::OnOutputSurfaceInitializeAttempted(
314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool success,
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const RendererCapabilities& capabilities) {
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsMainThread());
317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(layer_tree_host());
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (success) {
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    renderer_capabilities_main_thread_copy_ = capabilities;
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LayerTreeHost::CreateResult result =
324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      layer_tree_host()->OnCreateAndInitializeOutputSurfaceAttempted(success);
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (result == LayerTreeHost::CreateFailedButTryAgain) {
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!output_surface_creation_callback_.callback().is_null()) {
327eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      Proxy::MainThreadTaskRunner()->PostTask(
328eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          FROM_HERE, output_surface_creation_callback_.callback());
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    output_surface_creation_callback_.Cancel();
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
335558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid ThreadProxy::SendCommitRequestToImplThreadIfNeeded() {
336558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DCHECK(IsMainThread());
337558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (commit_request_sent_to_impl_thread_)
338558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return;
339558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  commit_request_sent_to_impl_thread_ = true;
340558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
341558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      FROM_HERE,
342558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      base::Bind(&ThreadProxy::SetNeedsCommitOnImplThread,
343558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                 impl_thread_weak_ptr_));
344558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
345558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const RendererCapabilities& ThreadProxy::GetRendererCapabilities() const {
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsMainThread());
348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!layer_tree_host()->output_surface_lost());
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return renderer_capabilities_main_thread_copy_;
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SetNeedsAnimate() {
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (animate_requested_)
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetNeedsAnimate");
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  animate_requested_ = true;
359558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  can_cancel_commit_ = false;
360558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  SendCommitRequestToImplThreadIfNeeded();
361558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
363558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid ThreadProxy::SetNeedsUpdateLayers() {
364558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DCHECK(IsMainThread());
3651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (commit_request_sent_to_impl_thread_)
3671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
3681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetNeedsUpdateLayers");
3691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
370558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  SendCommitRequestToImplThreadIfNeeded();
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SetNeedsCommit() {
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
375558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Unconditionally set here to handle SetNeedsCommit calls during a commit.
376558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  can_cancel_commit_ = false;
377558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (commit_requested_)
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetNeedsCommit");
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  commit_requested_ = true;
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
383558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  SendCommitRequestToImplThreadIfNeeded();
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::DidLoseOutputSurfaceOnImplThread() {
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurfaceOnImplThread");
38968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  CheckOutputSurfaceStatusOnImplThread();
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::CheckOutputSurfaceStatusOnImplThread() {
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::CheckOutputSurfaceStatusOnImplThread");
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_tree_host_impl_->IsContextLost())
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
397424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (cc::ContextProvider* offscreen_contexts =
398424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)          layer_tree_host_impl_->offscreen_context_provider())
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    offscreen_contexts->VerifyContexts();
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->DidLoseOutputSurface();
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::OnSwapBuffersCompleteOnImplThread() {
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::OnSwapBuffersCompleteOnImplThread");
406eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::MainThreadTaskRunner()->PostTask(
407eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ThreadProxy::DidCompleteSwapBuffers, main_thread_weak_ptr_));
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ThreadProxy::SetNeedsBeginImplFrame(bool enable) {
412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsImplThread());
4138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  TRACE_EVENT1("cc", "ThreadProxy::SetNeedsBeginImplFrame",
4147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)               "enable", enable);
4151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  layer_tree_host_impl_->SetNeedsBeginImplFrame(enable);
41668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UpdateBackgroundAnimateTicking();
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ThreadProxy::BeginImplFrame(const BeginFrameArgs& args) {
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsImplThread());
4211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::BeginImplFrame");
42268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
42368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Sample the frame time now. This time will be used for updating animations
42468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // when we draw.
42568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  layer_tree_host_impl_->CurrentFrameTimeTicks();
42668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
4278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scheduler_on_impl_thread_->BeginImplFrame(args);
42868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
42968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::OnCanDrawStateChanged(bool can_draw) {
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT1(
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "cc", "ThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw);
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->SetCanDraw(can_draw);
435424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  UpdateBackgroundAnimateTicking();
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
438424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void ThreadProxy::NotifyReadyToActivate() {
439424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::NotifyReadyToActivate");
440424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  scheduler_on_impl_thread_->NotifyReadyToActivate();
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SetNeedsCommitOnImplThread() {
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetNeedsCommitOnImplThread");
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->SetNeedsCommit();
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<AnimationEventsVector> events,
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::Time wall_clock_time) {
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc",
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               "ThreadProxy::PostAnimationEventsToMainThreadOnImplThread");
455eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::MainThreadTaskRunner()->PostTask(
456eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
457eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(&ThreadProxy::SetAnimationEvents,
458eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 main_thread_weak_ptr_,
459eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 base::Passed(&events),
460eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 wall_clock_time));
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ThreadProxy::ReduceContentsTextureMemoryOnImplThread(size_t limit_bytes,
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                          int priority_cutoff) {
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!contents_texture_manager_on_impl_thread())
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
4694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!layer_tree_host_impl_->resource_provider())
4704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return false;
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool reduce_result = contents_texture_manager_on_impl_thread()->
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ReduceMemoryOnImplThread(limit_bytes,
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               priority_cutoff,
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               layer_tree_host_impl_->resource_provider());
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!reduce_result)
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The texture upload queue may reference textures that were just purged,
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // clear them from the queue.
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (current_resource_update_controller_on_impl_thread_) {
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_resource_update_controller_on_impl_thread_->
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DiscardUploadsToEvictedResources();
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SendManagedMemoryStats() {
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_tree_host_impl_)
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
492f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!contents_texture_manager_on_impl_thread())
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we are using impl-side painting, then SendManagedMemoryStats is called
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // directly after the tile manager's manage function, and doesn't need to
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // interact with main thread's layer tree.
498f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (layer_tree_host_impl_->settings().impl_side_painting)
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_impl_->SendManagedMemoryStats(
502f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      contents_texture_manager_on_impl_thread()->MemoryVisibleBytes(),
503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      contents_texture_manager_on_impl_thread()->
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          MemoryVisibleAndNearbyBytes(),
505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      contents_texture_manager_on_impl_thread()->MemoryUseBytes());
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ThreadProxy::IsInsideDraw() { return inside_draw_; }
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::SetNeedsRedraw(gfx::Rect damage_rect) {
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetNeedsRedraw");
513eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
514eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
515eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(&ThreadProxy::SetNeedsRedrawRectOnImplThread,
516eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 impl_thread_weak_ptr_,
517eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 damage_rect));
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
520424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void ThreadProxy::SetNextCommitWaitsForActivation() {
521424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(IsMainThread());
522424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!inside_commit_);
523424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  commit_waits_for_activation_ = true;
524424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
525424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SetDeferCommits(bool defer_commits) {
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_NE(defer_commits_, defer_commits);
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  defer_commits_ = defer_commits;
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (defer_commits_)
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT_ASYNC_BEGIN0("cc", "ThreadProxy::SetDeferCommits", this);
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT_ASYNC_END0("cc", "ThreadProxy::SetDeferCommits", this);
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!defer_commits_ && pending_deferred_commit_)
537eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::MainThreadTaskRunner()->PostTask(
538eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
5391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        base::Bind(&ThreadProxy::BeginMainFrame,
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   main_thread_weak_ptr_,
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   base::Passed(&pending_deferred_commit_)));
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ThreadProxy::CommitRequested() const {
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return commit_requested_;
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool ThreadProxy::BeginMainFrameRequested() const {
5501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(IsMainThread());
5511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return commit_request_sent_to_impl_thread_;
5521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
5531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SetNeedsRedrawOnImplThread() {
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetNeedsRedrawOnImplThread");
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->SetNeedsRedraw();
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
560d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void ThreadProxy::SetNeedsManageTilesOnImplThread() {
561d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK(IsImplThread());
562d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  scheduler_on_impl_thread_->SetNeedsManageTiles();
563d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
564d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::SetNeedsRedrawRectOnImplThread(gfx::Rect damage_rect) {
566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsImplThread());
567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_impl_->SetViewportDamage(damage_rect);
568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetNeedsRedrawOnImplThread();
569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
57158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void ThreadProxy::SetSwapUsedIncompleteTileOnImplThread(
57258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool used_incomplete_tile) {
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
57458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (used_incomplete_tile) {
57558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    TRACE_EVENT_INSTANT0(
57658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        "cc",
57758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        "ThreadProxy::SetSwapUsedIncompleteTileOnImplThread",
57858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        TRACE_EVENT_SCOPE_THREAD);
57958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
58058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scheduler_on_impl_thread_->SetSwapUsedIncompleteTile(
58158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    used_incomplete_tile);
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::DidInitializeVisibleTileOnImplThread() {
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::DidInitializeVisibleTileOnImplThread");
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->SetNeedsRedraw();
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::MainThreadHasStoppedFlinging() {
591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsMainThread());
592eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
593eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&ThreadProxy::MainThreadHasStoppedFlingingOnImplThread,
595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 impl_thread_weak_ptr_));
596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::MainThreadHasStoppedFlingingOnImplThread() {
599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsImplThread());
60090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  layer_tree_host_impl_->MainThreadHasStoppedFlinging();
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
603a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void ThreadProxy::NotifyInputThrottledUntilCommit() {
604a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(IsMainThread());
605a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Proxy::ImplThreadTaskRunner()->PostTask(
606a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      FROM_HERE,
607a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      base::Bind(&ThreadProxy::SetInputThrottledUntilCommitOnImplThread,
608a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                 impl_thread_weak_ptr_,
609a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                 true));
610a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
611a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
612a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void ThreadProxy::SetInputThrottledUntilCommitOnImplThread(
613a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    bool is_throttled) {
614a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(IsImplThread());
615a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (is_throttled == input_throttled_until_commit_)
616a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return;
617a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  input_throttled_until_commit_ = is_throttled;
618a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  RenewTreePriority();
619a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
620a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
621f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)LayerTreeHost* ThreadProxy::layer_tree_host() {
622f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(IsMainThread() || IsMainThreadBlocked());
623f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return layer_tree_host_unsafe_;
624f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
625f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
626f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const LayerTreeHost* ThreadProxy::layer_tree_host() const {
627f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(IsMainThread() || IsMainThreadBlocked());
628f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return layer_tree_host_unsafe_;
629f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
630f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
631f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)PrioritizedResourceManager*
632f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ThreadProxy::contents_texture_manager_on_main_thread() {
633f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(IsMainThread() || IsMainThreadBlocked());
634f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return layer_tree_host()->contents_texture_manager();
635f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
636f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
637f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)PrioritizedResourceManager*
638f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ThreadProxy::contents_texture_manager_on_impl_thread() {
639f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(IsImplThread());
640f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return contents_texture_manager_unsafe_;
641f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
642f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::Start(scoped_ptr<OutputSurface> first_output_surface) {
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
645eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(Proxy::HasImplThread());
646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(first_output_surface);
647424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create LayerTreeHostImpl.
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DebugScopedSetMainThreadBlocked main_thread_blocked(this);
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CompletionEvent completion;
651eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
652eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ThreadProxy::InitializeImplOnImplThread,
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(this),
65590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 &completion));
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion.Wait();
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  main_thread_weak_ptr_ = weak_factory_.GetWeakPtr();
659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  first_output_surface_ = first_output_surface.Pass();
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  started_ = true;
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::Stop() {
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::Stop");
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(started_);
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Synchronously finishes pending GL operations and deletes the impl.
670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The two steps are done as separate post tasks, so that tasks posted
671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // by the GL implementation due to the Finish can be executed by the
672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // renderer before shutting it down.
673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  {
674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CompletionEvent completion;
677eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
678eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&ThreadProxy::FinishGLOnImplThread,
680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   impl_thread_weak_ptr_,
681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   &completion));
682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    completion.Wait();
683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompletionEvent completion;
688eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
689eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&ThreadProxy::LayerTreeHostClosedOnImplThread,
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   impl_thread_weak_ptr_,
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   &completion));
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    completion.Wait();
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  weak_factory_.InvalidateWeakPtrs();
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!layer_tree_host_impl_.get());  // verify that the impl deleted.
699f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  contents_texture_manager_unsafe_ = NULL;
700f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host_unsafe_ = NULL;
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  started_ = false;
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::ForceSerializeOnSwapBuffers() {
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DebugScopedSetMainThreadBlocked main_thread_blocked(this);
7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CompletionEvent completion;
707eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
708eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ThreadProxy::ForceSerializeOnSwapBuffersOnImplThread,
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 impl_thread_weak_ptr_,
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 &completion));
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion.Wait();
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::ForceSerializeOnSwapBuffersOnImplThread(
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompletionEvent* completion) {
717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (layer_tree_host_impl_->renderer())
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host_impl_->renderer()->DoNoOp();
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion->Signal();
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::FinishAllRenderingOnImplThread(CompletionEvent* completion) {
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::FinishAllRenderingOnImplThread");
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_impl_->FinishAllRendering();
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion->Signal();
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ThreadProxy::ScheduledActionSendBeginMainFrame() {
7308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionSendBeginMainFrame");
7311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state(
7321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      new BeginMainFrameAndCommitState);
7331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  begin_main_frame_state->monotonic_frame_begin_time =
7347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      layer_tree_host_impl_->CurrentPhysicalTimeTicks();
7351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  begin_main_frame_state->scroll_info =
73690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      layer_tree_host_impl_->ProcessScrollDeltas();
737eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
738eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!layer_tree_host_impl_->settings().impl_side_painting) {
739eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    DCHECK_GT(layer_tree_host_impl_->memory_allocation_limit_bytes(), 0u);
740eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
7411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  begin_main_frame_state->memory_allocation_limit_bytes =
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_tree_host_impl_->memory_allocation_limit_bytes();
7431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  begin_main_frame_state->memory_allocation_priority_cutoff =
74468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      layer_tree_host_impl_->memory_allocation_priority_cutoff();
7451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  begin_main_frame_state->evicted_ui_resources =
74658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      layer_tree_host_impl_->EvictedUIResourcesExist();
747eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::MainThreadTaskRunner()->PostTask(
748eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
7491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      base::Bind(&ThreadProxy::BeginMainFrame,
75090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 main_thread_weak_ptr_,
7511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                 base::Passed(&begin_main_frame_state)));
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (begin_main_frame_sent_completion_event_on_impl_thread_) {
7541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    begin_main_frame_sent_completion_event_on_impl_thread_->Signal();
7551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    begin_main_frame_sent_completion_event_on_impl_thread_ = NULL;
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  begin_main_frame_sent_time_ = base::TimeTicks::HighResNow();
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ThreadProxy::BeginMainFrame(
7611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state) {
7621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::BeginMainFrame");
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
7643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
765f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!layer_tree_host())
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (defer_commits_) {
7691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    pending_deferred_commit_ = begin_main_frame_state.Pass();
770f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    layer_tree_host()->DidDeferCommit();
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "EarlyOut_DeferCommits");
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
775f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // If the commit finishes, LayerTreeHost will transfer its swap promises to
776f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // LayerTreeImpl. The destructor of SwapPromiseChecker checks LayerTressHost's
777f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // swap promises.
778f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SwapPromiseChecker swap_promise_checker(layer_tree_host());
779f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Do not notify the impl thread of commit requests that occur during
7811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // the apply/animate/layout part of the BeginMainFrameAndCommit process since
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // those commit requests will get painted immediately. Once we have done
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the paint, commit_requested_ will be set to false to allow new commit
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // requests to be scheduled.
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  commit_requested_ = true;
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  commit_request_sent_to_impl_thread_ = true;
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // On the other hand, the AnimationRequested flag needs to be cleared
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // here so that any animation requests generated by the apply or animate
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // callbacks will trigger another frame.
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  animate_requested_ = false;
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
793f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!in_composite_and_readback_ && !layer_tree_host()->visible()) {
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    commit_requested_ = false;
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    commit_request_sent_to_impl_thread_ = false;
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "EarlyOut_NotVisible");
798558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    bool did_handle = false;
799eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
800eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
8011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        base::Bind(&ThreadProxy::BeginMainFrameAbortedOnImplThread,
802558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                   impl_thread_weak_ptr_,
803558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                   did_handle));
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
807f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (begin_main_frame_state) {
808f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    layer_tree_host()->ApplyScrollAndScale(
809f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        *begin_main_frame_state->scroll_info);
810f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
811558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
812f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->WillBeginMainFrame();
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (begin_main_frame_state) {
815f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    layer_tree_host()->UpdateClientAnimations(
8161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        begin_main_frame_state->monotonic_frame_begin_time);
817f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    layer_tree_host()->AnimateLayers(
8181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        begin_main_frame_state->monotonic_frame_begin_time);
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Unlink any backings that the impl thread has evicted, so that we know to
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // re-paint them in UpdateLayers.
823f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (contents_texture_manager_on_main_thread()) {
824f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    contents_texture_manager_on_main_thread()->
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        UnlinkAndClearEvictedBackings();
82668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
8271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (begin_main_frame_state) {
828f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      contents_texture_manager_on_main_thread()->SetMaxMemoryLimitBytes(
8291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          begin_main_frame_state->memory_allocation_limit_bytes);
830f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      contents_texture_manager_on_main_thread()->SetExternalPriorityCutoff(
8311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          begin_main_frame_state->memory_allocation_priority_cutoff);
83268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
83558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Recreate all UI resources if there were evicted UI resources when the impl
83658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // thread initiated the commit.
8371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool evicted_ui_resources = begin_main_frame_state
8381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                  ? begin_main_frame_state->evicted_ui_resources
8391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                  : false;
84058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (evicted_ui_resources)
841f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      layer_tree_host()->RecreateUIResources();
84258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
843f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->Layout();
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Clear the commit flag after updating animations and layout here --- objects
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // that only layout when painted will trigger another SetNeedsCommit inside
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // UpdateLayers.
8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  commit_requested_ = false;
8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  commit_request_sent_to_impl_thread_ = false;
850558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  bool can_cancel_this_commit =
85158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      can_cancel_commit_ &&
85258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      !in_composite_and_readback_ &&
85358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      !evicted_ui_resources;
854558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  can_cancel_commit_ = true;
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceUpdateQueue> queue =
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new ResourceUpdateQueue);
85868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
859f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool updated = layer_tree_host()->UpdateLayers(queue.get());
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Once single buffered layers are committed, they cannot be modified until
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // they are drawn by the impl thread.
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  textures_acquired_ = false;
8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
865f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->WillCommit();
866558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
867558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (!updated && can_cancel_this_commit) {
868558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    TRACE_EVENT0("cc", "EarlyOut_NoUpdates");
869558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    bool did_handle = true;
870558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
871558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        FROM_HERE,
8721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        base::Bind(&ThreadProxy::BeginMainFrameAbortedOnImplThread,
873558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                   impl_thread_weak_ptr_,
874558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                   did_handle));
875558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
876558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    // Although the commit is internally aborted, this is because it has been
877558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    // detected to be a no-op.  From the perspective of an embedder, this commit
878558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    // went through, and input should no longer be throttled, etc.
879f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    layer_tree_host()->CommitComplete();
880f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    layer_tree_host()->DidBeginMainFrame();
881558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return;
882558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
883558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
884558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Before calling animate, we set animate_requested_ to false. If it is true
885558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // now, it means SetNeedAnimate was called again, but during a state when
886558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // commit_request_sent_to_impl_thread_ = true. We need to force that call to
887558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // happen again now so that the commit request is sent to the impl thread.
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (animate_requested_) {
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Forces SetNeedsAnimate to consider posting a commit task.
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    animate_requested_ = false;
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetNeedsAnimate();
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<cc::ContextProvider> offscreen_context_provider;
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (renderer_capabilities_main_thread_copy_.using_offscreen_context3d &&
896f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      layer_tree_host()->needs_offscreen_context()) {
8974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    offscreen_context_provider =
898f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        layer_tree_host()->client()->OffscreenContextProvider();
899868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (offscreen_context_provider.get())
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      created_offscreen_context_provider_ = true;
9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
90390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Notify the impl thread that the main thread is ready to commit. This will
9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // begin the commit process, which is blocking from the main thread's
9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // point of view, but asynchronously performed on the impl thread,
9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // coordinated by the Scheduler.
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
9081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    TRACE_EVENT0("cc", "ThreadProxy::BeginMainFrame::commit");
9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
912424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // This CapturePostTasks should be destroyed before CommitComplete() is
913424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // called since that goes out to the embedder, and we want the embedder
914424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // to receive its callbacks before that.
915424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    BlockingTaskRunner::CapturePostTasks blocked;
916424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompletionEvent completion;
918eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
919eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
92090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        base::Bind(&ThreadProxy::StartCommitOnImplThread,
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   impl_thread_weak_ptr_,
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   &completion,
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   queue.release(),
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   offscreen_context_provider));
9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    completion.Wait();
9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    RenderingStatsInstrumentation* stats_instrumentation =
928f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        layer_tree_host()->rendering_stats_instrumentation();
9294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    BenchmarkInstrumentation::IssueMainThreadRenderingStatsEvent(
9304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        stats_instrumentation->main_thread_rendering_stats());
9313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    stats_instrumentation->AccumulateAndClearMainThreadStats();
9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
934f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->CommitComplete();
935f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->DidBeginMainFrame();
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
93890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void ThreadProxy::StartCommitOnImplThread(
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompletionEvent* completion,
9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceUpdateQueue* raw_queue,
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<cc::ContextProvider> offscreen_context_provider) {
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceUpdateQueue> queue(raw_queue);
9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
94490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::StartCommitOnImplThread");
9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!commit_completion_event_on_impl_thread_);
9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread() && IsMainThreadBlocked());
9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(scheduler_on_impl_thread_);
9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(scheduler_on_impl_thread_->CommitPending());
9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_tree_host_impl_) {
9512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "EarlyOut_NoLayerTree");
9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    completion->Signal();
9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
956868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (offscreen_context_provider.get())
9572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    offscreen_context_provider->BindToCurrentThread();
958424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  layer_tree_host_impl_->SetOffscreenContextProvider(
959424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      offscreen_context_provider);
9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
961f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (contents_texture_manager_unsafe_) {
962f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK_EQ(contents_texture_manager_unsafe_,
963f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              contents_texture_manager_on_main_thread());
964f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
965f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Cache this pointer that was created on the main thread side to avoid a
966f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // data race between creating it and using it on the compositor thread.
967f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    contents_texture_manager_unsafe_ =
968f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        contents_texture_manager_on_main_thread();
969f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
970f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
971f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (contents_texture_manager_on_main_thread()) {
972f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (contents_texture_manager_on_main_thread()->
973868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            LinkedEvictedBackingsExist()) {
974868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // Clear any uploads we were making to textures linked to evicted
975868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // resources
976868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      queue->ClearUploadsToEvictedResources();
977868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // Some textures in the layer tree are invalid. Kick off another commit
978868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // to fill them again.
979868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      SetNeedsCommitOnImplThread();
980868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
982f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    contents_texture_manager_on_main_thread()->
983868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        PushTexturePrioritiesToBackings();
984868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  commit_completion_event_on_impl_thread_ = completion;
987eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  current_resource_update_controller_on_impl_thread_ =
988eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      ResourceUpdateController::Create(
989eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          this,
990eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          Proxy::ImplThreadTaskRunner(),
991eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          queue.Pass(),
992eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          layer_tree_host_impl_->resource_provider());
993eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  current_resource_update_controller_on_impl_thread_->PerformMoreUpdates(
994eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      scheduler_on_impl_thread_->AnticipatedDrawTime());
9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ThreadProxy::BeginMainFrameAbortedOnImplThread(bool did_handle) {
9981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::BeginMainFrameAbortedOnImplThread");
9992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(scheduler_on_impl_thread_);
10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(scheduler_on_impl_thread_->CommitPending());
1002558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DCHECK(!layer_tree_host_impl_->pending_tree());
1003558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1004558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // If the begin frame data was handled, then scroll and scale set was applied
1005558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // by the main thread, so the active tree needs to be updated as if these sent
1006558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // values were applied and committed.
1007a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (did_handle) {
10083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    layer_tree_host_impl_->active_tree()
10093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        ->ApplySentScrollAndScaleDeltasFromAbortedCommit();
10103240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    layer_tree_host_impl_->active_tree()->ResetContentsTexturesPurged();
1011a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    SetInputThrottledUntilCommitOnImplThread(false);
1012a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
10138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scheduler_on_impl_thread_->BeginMainFrameAborted(did_handle);
10142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::ScheduledActionCommit() {
10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionCommit");
10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(commit_completion_event_on_impl_thread_);
1020eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(current_resource_update_controller_on_impl_thread_);
1021eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1022eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Complete all remaining texture updates.
1023eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  current_resource_update_controller_on_impl_thread_->Finalize();
1024eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  current_resource_update_controller_on_impl_thread_.reset();
10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1026424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  inside_commit_ = true;
10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_impl_->BeginCommit();
1028f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->BeginCommitOnImplThread(layer_tree_host_impl_.get());
1029f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->FinishCommitOnImplThread(layer_tree_host_impl_.get());
10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_impl_->CommitComplete();
1031424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  inside_commit_ = false;
10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1033a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SetInputThrottledUntilCommitOnImplThread(false);
1034a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1035424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  UpdateBackgroundAnimateTicking();
1036c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  next_frame_is_newly_committed_frame_on_impl_thread_ = true;
10382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1039f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (layer_tree_host()->settings().impl_side_painting &&
1040424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      commit_waits_for_activation_) {
10412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // For some layer types in impl-side painting, the commit is held until
10427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // the pending tree is activated.  It's also possible that the
10437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // pending tree has already activated if there was no work to be done.
1044c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TRACE_EVENT_INSTANT0("cc", "HoldCommit", TRACE_EVENT_SCOPE_THREAD);
10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    completion_event_for_commit_held_on_tree_activation_ =
10462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        commit_completion_event_on_impl_thread_;
10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    commit_completion_event_on_impl_thread_ = NULL;
10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    commit_completion_event_on_impl_thread_->Signal();
10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    commit_completion_event_on_impl_thread_ = NULL;
10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1053424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  commit_waits_for_activation_ = false;
1054424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
10557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  commit_complete_time_ = base::TimeTicks::HighResNow();
10561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  begin_main_frame_to_commit_duration_history_.InsertSample(
10571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      commit_complete_time_ - begin_main_frame_sent_time_);
10587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // SetVisible kicks off the next scheduler action, so this must be last.
10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1063ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ThreadProxy::ScheduledActionUpdateVisibleTiles() {
10642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
1065ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionUpdateVisibleTiles");
1066ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  layer_tree_host_impl_->UpdateVisibleTiles();
10672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1069424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void ThreadProxy::ScheduledActionActivatePendingTree() {
10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
1071424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionActivatePendingTree");
1072424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  layer_tree_host_impl_->ActivatePendingTree();
10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1075c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::ScheduledActionBeginOutputSurfaceCreation() {
10762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
10773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionBeginOutputSurfaceCreation");
1078eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::MainThreadTaskRunner()->PostTask(
1079eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
1080c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&ThreadProxy::CreateAndInitializeOutputSurface,
1081c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 main_thread_weak_ptr_));
10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
108458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)DrawSwapReadbackResult ThreadProxy::DrawSwapReadbackInternal(
108558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool forced_draw,
108658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool swap_requested,
108758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool readback_requested) {
108858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DrawSwapReadbackResult result;
10892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  result.did_draw = false;
10902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  result.did_swap = false;
109158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  result.did_readback = false;
10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(layer_tree_host_impl_.get());
10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_tree_host_impl_)
10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return result;
10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(layer_tree_host_impl_->renderer());
10982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_tree_host_impl_->renderer())
10992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return result;
11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
110168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::TimeTicks start_time = base::TimeTicks::HighResNow();
110268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::TimeDelta draw_duration_estimate = DrawDurationEstimate();
110368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::AutoReset<bool> mark_inside(&inside_draw_, true);
110468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
110568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Advance our animations.
1106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::TimeTicks monotonic_time =
1107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      layer_tree_host_impl_->CurrentFrameTimeTicks();
1108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::Time wall_clock_time = layer_tree_host_impl_->CurrentFrameTime();
11094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(enne): This should probably happen post-animate.
11114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (layer_tree_host_impl_->pending_tree())
11124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    layer_tree_host_impl_->pending_tree()->UpdateDrawProperties();
11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_impl_->Animate(monotonic_time, wall_clock_time);
11147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This method is called on a forced draw, regardless of whether we are able
11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to produce a frame, as the calling site on main thread is blocked until its
1117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // request completes, and we signal completion here. If CanDraw() is false, we
11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // will indicate success=false to the caller, but we must still signal
11192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // completion to avoid deadlock.
11202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // We guard PrepareToDraw() with CanDraw() because it always returns a valid
11222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // frame, so can only be used when such a frame is possible. Since
1123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
1124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // CanDraw() as well.
1125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
112658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool drawing_for_readback =
112758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      readback_requested && !!readback_request_on_impl_thread_;
1128b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  bool can_do_readback = layer_tree_host_impl_->renderer()->CanReadPixels();
11292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerTreeHostImpl::FrameData frame;
1131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool draw_frame = false;
1132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1133b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (layer_tree_host_impl_->CanDraw() &&
1134b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      (!drawing_for_readback || can_do_readback)) {
1135b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    // If it is for a readback, make sure we draw the portion being read back.
1136b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    gfx::Rect readback_rect;
1137b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    if (drawing_for_readback)
1138b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      readback_rect = readback_request_on_impl_thread_->rect;
1139b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (layer_tree_host_impl_->PrepareToDraw(&frame, readback_rect) ||
1141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        forced_draw)
1142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      draw_frame = true;
1143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (draw_frame) {
11462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host_impl_->DrawLayers(
11472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &frame,
11488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        scheduler_on_impl_thread_->LastBeginImplFrameTime());
1149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    result.did_draw = true;
11502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_impl_->DidDrawAllLayers(frame);
115268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
115368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  bool start_ready_animations = draw_frame;
1154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
1155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check for a pending CompositeAndReadback.
115758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (drawing_for_readback) {
115858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(!swap_requested);
115958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    result.did_readback = false;
116058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (draw_frame && !layer_tree_host_impl_->IsContextLost()) {
11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_tree_host_impl_->Readback(readback_request_on_impl_thread_->pixels,
11622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      readback_request_on_impl_thread_->rect);
116358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      result.did_readback = true;
11642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
116558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    readback_request_on_impl_thread_->success = result.did_readback;
11662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    readback_request_on_impl_thread_->completion.Signal();
11672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    readback_request_on_impl_thread_ = NULL;
11682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (draw_frame) {
116958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(swap_requested);
1170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    result.did_swap = layer_tree_host_impl_->SwapBuffers(frame);
11712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
117258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // We don't know if we have incomplete tiles if we didn't actually swap.
117358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (result.did_swap) {
117458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      DCHECK(!frame.has_no_damage);
117558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      SetSwapUsedIncompleteTileOnImplThread(frame.contains_incomplete_tile);
117658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
11772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Tell the main thread that the the newly-commited frame was drawn.
11802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (next_frame_is_newly_committed_frame_on_impl_thread_) {
11812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    next_frame_is_newly_committed_frame_on_impl_thread_ = false;
1182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::MainThreadTaskRunner()->PostTask(
1183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
11842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&ThreadProxy::DidCommitAndDrawFrame, main_thread_weak_ptr_));
11852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (draw_frame) {
11882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CheckOutputSurfaceStatusOnImplThread();
11892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::TimeDelta draw_duration = base::TimeTicks::HighResNow() - start_time;
11917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    draw_duration_history_.InsertSample(draw_duration);
11927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::TimeDelta draw_duration_overestimate;
11937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::TimeDelta draw_duration_underestimate;
11947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (draw_duration > draw_duration_estimate)
11957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      draw_duration_underestimate = draw_duration - draw_duration_estimate;
11967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    else
11977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      draw_duration_overestimate = draw_duration_estimate - draw_duration;
11987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDuration",
11997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               draw_duration,
12007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               base::TimeDelta::FromMilliseconds(1),
12017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               base::TimeDelta::FromMilliseconds(100),
12027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               50);
12037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDurationUnderestimate",
12047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               draw_duration_underestimate,
12057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               base::TimeDelta::FromMilliseconds(1),
12067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               base::TimeDelta::FromMilliseconds(100),
12077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               50);
12087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDurationOverestimate",
12097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               draw_duration_overestimate,
12107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               base::TimeDelta::FromMilliseconds(1),
12117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               base::TimeDelta::FromMilliseconds(100),
12127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               50);
12137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
12147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
12152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return result;
12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::AcquireLayerTextures() {
12192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Called when the main thread needs to modify a layer texture that is used
12202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // directly by the compositor.
12212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This method will block until the next compositor draw if there is a
12222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // previously committed frame that is still undrawn. This is necessary to
12232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // ensure that the main thread does not monopolize access to the textures.
12242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
12252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (textures_acquired_)
12272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
12282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::AcquireLayerTextures");
12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DebugScopedSetMainThreadBlocked main_thread_blocked(this);
12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CompletionEvent completion;
1232eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
1233eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
12342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ThreadProxy::AcquireLayerTexturesForMainThreadOnImplThread,
12352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 impl_thread_weak_ptr_,
12362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 &completion));
12372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Block until it is safe to write to layer textures from the main thread.
12382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion.Wait();
12392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  textures_acquired_ = true;
1241558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  can_cancel_commit_ = false;
12422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::AcquireLayerTexturesForMainThreadOnImplThread(
12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompletionEvent* completion) {
12462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!texture_acquisition_completion_event_on_impl_thread_);
12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  texture_acquisition_completion_event_on_impl_thread_ = completion;
12502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->SetMainThreadNeedsLayerTextures();
12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::ScheduledActionAcquireLayerTexturesForMainThread() {
12542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(texture_acquisition_completion_event_on_impl_thread_);
12552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  texture_acquisition_completion_event_on_impl_thread_->Signal();
12562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  texture_acquisition_completion_event_on_impl_thread_ = NULL;
12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1259d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void ThreadProxy::ScheduledActionManageTiles() {
1260d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionManageTiles");
1261d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK(layer_tree_host_impl_->settings().impl_side_painting);
1262d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  layer_tree_host_impl_->ManageTiles();
1263d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
1264d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
126558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndSwapIfPossible() {
126658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndSwap");
126758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool forced_draw = false;
126858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool swap_requested = true;
126958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool readback_requested = false;
127058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return DrawSwapReadbackInternal(
127158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      forced_draw, swap_requested, readback_requested);
127258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
127358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
127458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndSwapForced() {
127558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndSwapForced");
127658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool forced_draw = true;
127758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool swap_requested = true;
127858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool readback_requested = false;
127958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return DrawSwapReadbackInternal(
128058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      forced_draw, swap_requested, readback_requested);
12812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
128358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndReadback() {
128458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndReadback");
128558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool forced_draw = true;
128658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool swap_requested = false;
128758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool readback_requested = true;
128858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return DrawSwapReadbackInternal(
128958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      forced_draw, swap_requested, readback_requested);
12902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) {
12932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (current_resource_update_controller_on_impl_thread_)
129468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    current_resource_update_controller_on_impl_thread_->PerformMoreUpdates(
129568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        time);
12962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)base::TimeDelta ThreadProxy::DrawDurationEstimate() {
12997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::TimeDelta historical_estimate =
13007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      draw_duration_history_.Percentile(kDrawDurationEstimationPercentile);
13017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::TimeDelta padding = base::TimeDelta::FromMicroseconds(
13027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      kDrawDurationEstimatePaddingInMicroseconds);
13037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return historical_estimate + padding;
13047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
13057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
13068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)base::TimeDelta ThreadProxy::BeginMainFrameToCommitDurationEstimate() {
13071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return begin_main_frame_to_commit_duration_history_.Percentile(
13087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      kCommitAndActivationDurationEstimationPercentile);
13097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
13107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
13117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbase::TimeDelta ThreadProxy::CommitToActivateDurationEstimate() {
13127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return commit_to_activate_duration_history_.Percentile(
13137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      kCommitAndActivationDurationEstimationPercentile);
13147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
13157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
13168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ThreadProxy::PostBeginImplFrameDeadline(const base::Closure& closure,
13178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                             base::TimeTicks deadline) {
13181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  base::TimeDelta delta = deadline - gfx::FrameTime::Now();
131968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (delta <= base::TimeDelta())
132068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    delta = base::TimeDelta();
132168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  Proxy::ImplThreadTaskRunner()->PostDelayedTask(FROM_HERE, closure, delta);
132268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
132368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
13248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ThreadProxy::DidBeginImplFrameDeadline() {
13258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame();
13268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
13278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
13282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::ReadyToFinalizeTextureUpdates() {
13292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
133090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scheduler_on_impl_thread_->FinishCommit();
13312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::DidCommitAndDrawFrame() {
13342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
1335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!layer_tree_host())
13362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->DidCommitAndDrawFrame();
13382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::DidCompleteSwapBuffers() {
13412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
1342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!layer_tree_host())
13432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->DidCompleteSwapBuffers();
13452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SetAnimationEvents(scoped_ptr<AnimationEventsVector> events,
13482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     base::Time wall_clock_time) {
13492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetAnimationEvents");
13502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
1351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!layer_tree_host())
13522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->SetAnimationEvents(events.Pass(), wall_clock_time);
13542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::CreateAndInitializeOutputSurface() {
1357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::CreateAndInitializeOutputSurface");
13582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
1359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check that output surface has not been recreated by CompositeAndReadback
1361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // after this task is posted but before it is run.
1362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool has_initialized_output_surface_on_impl_thread = true;
1363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  {
1364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CompletionEvent completion;
1365eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
1366eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
1367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&ThreadProxy::HasInitializedOutputSurfaceOnImplThread,
1368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   impl_thread_weak_ptr_,
1369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   &completion,
1370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   &has_initialized_output_surface_on_impl_thread));
1371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    completion.Wait();
1372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (has_initialized_output_surface_on_impl_thread)
1374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
1375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->DidLoseOutputSurface();
1377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  output_surface_creation_callback_.Reset(base::Bind(
1378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &ThreadProxy::DoCreateAndInitializeOutputSurface,
1379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Unretained(this)));
1380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  output_surface_creation_callback_.callback().Run();
13812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::HasInitializedOutputSurfaceOnImplThread(
1384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CompletionEvent* completion,
1385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool* has_initialized_output_surface) {
1386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsImplThread());
1387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  *has_initialized_output_surface =
1388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      scheduler_on_impl_thread_->HasInitializedOutputSurface();
1389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  completion->Signal();
13902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
139290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) {
13932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::InitializeImplOnImplThread");
13942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
1395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host_impl_ = layer_tree_host()->CreateLayerTreeHostImpl(this);
1396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const LayerTreeSettings& settings = layer_tree_host()->settings();
13972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SchedulerSettings scheduler_settings;
139868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  scheduler_settings.deadline_scheduling_enabled =
139968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      settings.deadline_scheduling_enabled;
1400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scheduler_settings.impl_side_painting = settings.impl_side_painting;
1401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scheduler_settings.timeout_and_draw_when_animation_checkerboards =
1402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      settings.timeout_and_draw_when_animation_checkerboards;
140358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ =
140458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      settings.maximum_number_of_failed_draws_before_draw_is_forced_;
14057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scheduler_settings.using_synchronous_renderer_compositor =
14067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      settings.using_synchronous_renderer_compositor;
1407eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scheduler_settings.throttle_frame_production =
1408eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      settings.throttle_frame_production;
14097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scheduler_on_impl_thread_ = Scheduler::Create(this, scheduler_settings);
14102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
14112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  impl_thread_weak_ptr_ = weak_factory_on_impl_thread_.GetWeakPtr();
14132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion->Signal();
14142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::InitializeOutputSurfaceOnImplThread(
14172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompletionEvent* completion,
1418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<OutputSurface> output_surface,
1419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<ContextProvider> offscreen_context_provider,
1420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool* success,
14212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RendererCapabilities* capabilities) {
1422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::InitializeOutputSurfaceOnImplThread");
14232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
1424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsMainThreadBlocked());
1425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(success);
1426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(capabilities);
1427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1428f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->DeleteContentsTexturesOnImplThread(
1429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      layer_tree_host_impl_->resource_provider());
1430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  *success = layer_tree_host_impl_->InitializeRenderer(output_surface.Pass());
1432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (*success) {
14342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *capabilities = layer_tree_host_impl_->GetRendererCapabilities();
1435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface();
1436424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  } else if (offscreen_context_provider.get()) {
1437424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (offscreen_context_provider->BindToCurrentThread())
1438424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      offscreen_context_provider->VerifyContexts();
1439424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    offscreen_context_provider = NULL;
14402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1442424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  layer_tree_host_impl_->SetOffscreenContextProvider(
1443424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      offscreen_context_provider);
1444868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
14452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion->Signal();
14462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::FinishGLOnImplThread(CompletionEvent* completion) {
1449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::FinishGLOnImplThread");
1450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsImplThread());
1451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (layer_tree_host_impl_->resource_provider())
1452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    layer_tree_host_impl_->resource_provider()->Finish();
1453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  completion->Signal();
1454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
14562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::LayerTreeHostClosedOnImplThread(CompletionEvent* completion) {
14572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::LayerTreeHostClosedOnImplThread");
14582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
1459f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->DeleteContentsTexturesOnImplThread(
14602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_tree_host_impl_->resource_provider());
14614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  current_resource_update_controller_on_impl_thread_.reset();
14621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  layer_tree_host_impl_->SetNeedsBeginImplFrame(false);
14632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_.reset();
1464a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  layer_tree_host_impl_.reset();
14652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  weak_factory_on_impl_thread_.InvalidateWeakPtrs();
14662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion->Signal();
14672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t ThreadProxy::MaxPartialTextureUpdates() const {
14702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ResourceUpdateController::MaxPartialTextureUpdates();
14712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ThreadProxy::BeginMainFrameAndCommitState::BeginMainFrameAndCommitState()
147468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    : memory_allocation_limit_bytes(0),
147568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      memory_allocation_priority_cutoff(0),
147668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      evicted_ui_resources(false) {}
14772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ThreadProxy::BeginMainFrameAndCommitState::~BeginMainFrameAndCommitState() {}
14792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<base::Value> ThreadProxy::AsValue() const {
14812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
14822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CompletionEvent completion;
14842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
14852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetMainThreadBlocked main_thread_blocked(
14862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        const_cast<ThreadProxy*>(this));
1487eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
1488eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
1489eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        base::Bind(&ThreadProxy::AsValueOnImplThread,
1490eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                   impl_thread_weak_ptr_,
1491eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                   &completion,
1492eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                   state.get()));
14932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    completion.Wait();
14942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return state.PassAs<base::Value>();
14962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::AsValueOnImplThread(CompletionEvent* completion,
14992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      base::DictionaryValue* state) const {
15002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state->Set("layer_tree_host_impl",
15012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             layer_tree_host_impl_->AsValue().release());
15022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion->Signal();
15032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ThreadProxy::CommitPendingForTesting() {
15062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
15072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CommitPendingRequest commit_pending_request;
15082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
15092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
1510eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
1511eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
15122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&ThreadProxy::CommitPendingOnImplThreadForTesting,
15132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   impl_thread_weak_ptr_,
15142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   &commit_pending_request));
15152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    commit_pending_request.completion.Wait();
15162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
15172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return commit_pending_request.commit_pending;
15182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::CommitPendingOnImplThreadForTesting(
15212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CommitPendingRequest* request) {
15222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
15232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (layer_tree_host_impl_->output_surface())
15242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    request->commit_pending = scheduler_on_impl_thread_->CommitPending();
15252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
15262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    request->commit_pending = false;
15272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request->completion.Signal();
15282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<base::Value> ThreadProxy::SchedulerStateAsValueForTesting() {
15317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (IsImplThread())
1532424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return scheduler_on_impl_thread_->StateAsValue().Pass();
15337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
15347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SchedulerStateRequest scheduler_state_request;
15357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  {
15367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
1537eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
1538eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
15393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        base::Bind(&ThreadProxy::SchedulerStateAsValueOnImplThreadForTesting,
15407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                   impl_thread_weak_ptr_,
15417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                   &scheduler_state_request));
15427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    scheduler_state_request.completion.Wait();
15437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
15443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return scheduler_state_request.state.Pass();
15457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
15467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
15473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ThreadProxy::SchedulerStateAsValueOnImplThreadForTesting(
15487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    SchedulerStateRequest* request) {
15497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(IsImplThread());
1550424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->state = scheduler_on_impl_thread_->StateAsValue();
15517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  request->completion.Signal();
15527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
15537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
15542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::RenewTreePriority() {
1555a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(IsImplThread());
15562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool smoothness_takes_priority =
15572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_tree_host_impl_->pinch_gesture_active() ||
15584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      layer_tree_host_impl_->IsCurrentlyScrolling() ||
15592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_tree_host_impl_->page_scale_animation_active();
15602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::TimeTicks now = layer_tree_host_impl_->CurrentPhysicalTimeTicks();
15627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
15632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Update expiration time if smoothness currently takes priority.
15642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (smoothness_takes_priority) {
15652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    smoothness_takes_priority_expiration_time_ =
15667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        now + base::TimeDelta::FromMilliseconds(
15677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                  kSmoothnessTakesPriorityExpirationDelay * 1000);
15682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
15692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We use the same priority for both trees by default.
15712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TreePriority priority = SAME_PRIORITY_FOR_BOTH_TREES;
15722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Smoothness takes priority if expiration time is in the future.
15747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (smoothness_takes_priority_expiration_time_ > now)
15752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    priority = SMOOTHNESS_TAKES_PRIORITY;
15762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // New content always takes priority when the active tree has
15782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // evicted resources or there is an invalid viewport size.
15792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (layer_tree_host_impl_->active_tree()->ContentsTexturesPurged() ||
1580a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      layer_tree_host_impl_->active_tree()->ViewportSizeInvalid() ||
158158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      layer_tree_host_impl_->EvictedUIResourcesExist() ||
1582a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      input_throttled_until_commit_)
15832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    priority = NEW_CONTENT_TAKES_PRIORITY;
15842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_impl_->SetTreePriority(priority);
15861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scheduler_on_impl_thread_->SetSmoothnessTakesPriority(
15871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      priority == SMOOTHNESS_TAKES_PRIORITY);
15882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notify the the client of this compositor via the output surface.
15902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(epenner): Route this to compositor-thread instead of output-surface
15912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // after GTFO refactor of compositor-thread (http://crbug/170828).
15922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (layer_tree_host_impl_->output_surface()) {
15932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host_impl_->output_surface()->
15942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        UpdateSmoothnessTakesPriority(priority == SMOOTHNESS_TAKES_PRIORITY);
15952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
15962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::TimeDelta delay = smoothness_takes_priority_expiration_time_ - now;
15982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Need to make sure a delayed task is posted when we have smoothness
16002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // takes priority expiration time in the future.
16012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (delay <= base::TimeDelta())
16022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
16032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (renew_tree_priority_on_impl_thread_pending_)
16042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
16052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1606eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostDelayedTask(
1607eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
16082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ThreadProxy::RenewTreePriorityOnImplThread,
16092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 weak_factory_on_impl_thread_.GetWeakPtr()),
16102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delay);
16112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  renew_tree_priority_on_impl_thread_pending_ = true;
16132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
16142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::RenewTreePriorityOnImplThread() {
16162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(renew_tree_priority_on_impl_thread_pending_);
16172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  renew_tree_priority_on_impl_thread_pending_ = false;
16182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RenewTreePriority();
16202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
16212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::RequestScrollbarAnimationOnImplThread(base::TimeDelta delay) {
1623eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostDelayedTask(
1624eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
16252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ThreadProxy::StartScrollbarAnimationOnImplThread,
16262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 impl_thread_weak_ptr_),
16272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delay);
16282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
16292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::StartScrollbarAnimationOnImplThread() {
16317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  layer_tree_host_impl_->StartScrollbarAnimation();
1632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1634a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void ThreadProxy::DidActivatePendingTree() {
1635a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  DCHECK(IsImplThread());
1636a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::DidActivatePendingTreeOnImplThread");
1637a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1638a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (completion_event_for_commit_held_on_tree_activation_ &&
1639a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      !layer_tree_host_impl_->pending_tree()) {
1640a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    TRACE_EVENT_INSTANT0("cc", "ReleaseCommitbyActivation",
1641a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                         TRACE_EVENT_SCOPE_THREAD);
1642a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    DCHECK(layer_tree_host_impl_->settings().impl_side_painting);
1643a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    completion_event_for_commit_held_on_tree_activation_->Signal();
1644a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    completion_event_for_commit_held_on_tree_activation_ = NULL;
1645a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
16467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1647424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  UpdateBackgroundAnimateTicking();
1648424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
16497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  commit_to_activate_duration_history_.InsertSample(
16507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::TimeTicks::HighResNow() - commit_complete_time_);
1651a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
1652a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1653f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ThreadProxy::DidManageTiles() {
1654f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(IsImplThread());
1655f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler_on_impl_thread_->DidManageTiles();
1656f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1657f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
16582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
1659