Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / cc / trees / thread_proxy.cc
index 15a1521..14e2181 100644 (file)
@@ -4,67 +4,42 @@
 
 #include "cc/trees/thread_proxy.h"
 
+#include <algorithm>
 #include <string>
 
 #include "base/auto_reset.h"
 #include "base/bind.h"
 #include "base/debug/trace_event.h"
+#include "base/debug/trace_event_argument.h"
 #include "base/debug/trace_event_synthetic_delay.h"
-#include "base/metrics/histogram.h"
 #include "cc/base/swap_promise.h"
 #include "cc/debug/benchmark_instrumentation.h"
+#include "cc/debug/devtools_instrumentation.h"
 #include "cc/input/input_handler.h"
 #include "cc/output/context_provider.h"
 #include "cc/output/output_surface.h"
 #include "cc/quads/draw_quad.h"
 #include "cc/resources/prioritized_resource_manager.h"
 #include "cc/scheduler/delay_based_time_source.h"
-#include "cc/scheduler/frame_rate_controller.h"
 #include "cc/scheduler/scheduler.h"
 #include "cc/trees/blocking_task_runner.h"
 #include "cc/trees/layer_tree_host.h"
 #include "cc/trees/layer_tree_impl.h"
+#include "cc/trees/scoped_abort_remaining_swap_promises.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
 #include "ui/gfx/frame_time.h"
 
+namespace cc {
+
 namespace {
 
 // Measured in seconds.
 const double kSmoothnessTakesPriorityExpirationDelay = 0.25;
 
-const size_t kDurationHistorySize = 60;
-const double kCommitAndActivationDurationEstimationPercentile = 50.0;
-const double kDrawDurationEstimationPercentile = 100.0;
-const int kDrawDurationEstimatePaddingInMicroseconds = 0;
-
-class SwapPromiseChecker {
- public:
-  explicit SwapPromiseChecker(cc::LayerTreeHost* layer_tree_host)
-      : layer_tree_host_(layer_tree_host) {}
-
-  ~SwapPromiseChecker() {
-    layer_tree_host_->BreakSwapPromises(cc::SwapPromise::COMMIT_FAILS);
-  }
-
- private:
-  cc::LayerTreeHost* layer_tree_host_;
-};
+unsigned int nextBeginFrameId = 0;
 
 }  // namespace
 
-namespace cc {
-
-struct ThreadProxy::ReadbackRequest {
-  CompletionEvent completion;
-  bool success;
-  void* pixels;
-  gfx::Rect rect;
-};
-
-struct ThreadProxy::CommitPendingRequest {
-  CompletionEvent completion;
-  bool commit_pending;
-};
-
 struct ThreadProxy::SchedulerStateRequest {
   CompletionEvent completion;
   scoped_ptr<base::Value> state;
@@ -72,18 +47,23 @@ struct ThreadProxy::SchedulerStateRequest {
 
 scoped_ptr<Proxy> ThreadProxy::Create(
     LayerTreeHost* layer_tree_host,
+    scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) {
-  return make_scoped_ptr(new ThreadProxy(layer_tree_host, impl_task_runner))
-      .PassAs<Proxy>();
+  return make_scoped_ptr(
+      new ThreadProxy(layer_tree_host, main_task_runner, impl_task_runner));
 }
 
 ThreadProxy::ThreadProxy(
     LayerTreeHost* layer_tree_host,
+    scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner)
-    : Proxy(impl_task_runner),
+    : Proxy(main_task_runner, impl_task_runner),
       main_thread_only_vars_unsafe_(this, layer_tree_host->id()),
       main_thread_or_blocked_vars_unsafe_(layer_tree_host),
-      compositor_thread_vars_unsafe_(this) {
+      compositor_thread_vars_unsafe_(
+          this,
+          layer_tree_host->id(),
+          layer_tree_host->rendering_stats_instrumentation()) {
   TRACE_EVENT0("cc", "ThreadProxy::ThreadProxy");
   DCHECK(IsMainThread());
   DCHECK(this->layer_tree_host());
@@ -95,10 +75,7 @@ ThreadProxy::MainThreadOnly::MainThreadOnly(ThreadProxy* proxy,
       animate_requested(false),
       commit_requested(false),
       commit_request_sent_to_impl_thread(false),
-      created_offscreen_context_provider(false),
       started(false),
-      textures_acquired(true),
-      in_composite_and_readback(false),
       manage_tiles_pending(false),
       can_cancel_commit(true),
       defer_commits(false),
@@ -119,21 +96,25 @@ ThreadProxy::MainThreadOrBlockedMainThread::contents_texture_manager() {
   return layer_tree_host->contents_texture_manager();
 }
 
-ThreadProxy::CompositorThreadOnly::CompositorThreadOnly(ThreadProxy* proxy)
-    : contents_texture_manager(NULL),
-      begin_main_frame_sent_completion_event(NULL),
-      readback_request(NULL),
+ThreadProxy::CompositorThreadOnly::CompositorThreadOnly(
+    ThreadProxy* proxy,
+    int layer_tree_host_id,
+    RenderingStatsInstrumentation* rendering_stats_instrumentation)
+    : layer_tree_host_id(layer_tree_host_id),
+      contents_texture_manager(NULL),
       commit_completion_event(NULL),
       completion_event_for_commit_held_on_tree_activation(NULL),
-      texture_acquisition_completion_event(NULL),
       next_frame_is_newly_committed_frame(false),
       inside_draw(false),
       input_throttled_until_commit(false),
-      renew_tree_priority_pending(false),
-      draw_duration_history(kDurationHistorySize),
-      begin_main_frame_to_commit_duration_history(kDurationHistorySize),
-      commit_to_activate_duration_history(kDurationHistorySize),
-      weak_factory(proxy) {}
+      smoothness_priority_expiration_notifier(
+          proxy->ImplThreadTaskRunner(),
+          base::Bind(&ThreadProxy::RenewTreePriority, base::Unretained(proxy)),
+          base::TimeDelta::FromMilliseconds(
+              kSmoothnessTakesPriorityExpirationDelay * 1000)),
+      timing_history(rendering_stats_instrumentation),
+      weak_factory(proxy) {
+}
 
 ThreadProxy::CompositorThreadOnly::~CompositorThreadOnly() {}
 
@@ -143,80 +124,6 @@ ThreadProxy::~ThreadProxy() {
   DCHECK(!main().started);
 }
 
-bool ThreadProxy::CompositeAndReadback(void* pixels, const gfx::Rect& rect) {
-  TRACE_EVENT0("cc", "ThreadProxy::CompositeAndReadback");
-  DCHECK(IsMainThread());
-  DCHECK(layer_tree_host());
-
-  if (main().defer_commits) {
-    TRACE_EVENT0("cc", "CompositeAndReadback_DeferCommit");
-    return false;
-  }
-
-  if (!layer_tree_host()->InitializeOutputSurfaceIfNeeded()) {
-    TRACE_EVENT0("cc", "CompositeAndReadback_EarlyOut_LR_Uninitialized");
-    return false;
-  }
-
-  // Perform a synchronous commit with an associated readback.
-  ReadbackRequest request;
-  request.rect = rect;
-  request.pixels = pixels;
-  {
-    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
-    CompletionEvent begin_main_frame_sent_completion;
-    Proxy::ImplThreadTaskRunner()->PostTask(
-        FROM_HERE,
-        base::Bind(&ThreadProxy::ForceCommitForReadbackOnImplThread,
-                   impl_thread_weak_ptr_,
-                   &begin_main_frame_sent_completion,
-                   &request));
-    begin_main_frame_sent_completion.Wait();
-  }
-
-  main().in_composite_and_readback = true;
-  // This is the forced commit.
-  // Note: The Impl thread also queues a separate BeginMainFrame on the
-  // main thread, which will be called after this CompositeAndReadback
-  // completes, to replace the forced commit.
-  BeginMainFrame(scoped_ptr<BeginMainFrameAndCommitState>());
-  main().in_composite_and_readback = false;
-
-  // Composite and readback requires a second commit to undo any changes
-  // that it made.
-  main().can_cancel_commit = false;
-
-  request.completion.Wait();
-  return request.success;
-}
-
-void ThreadProxy::ForceCommitForReadbackOnImplThread(
-    CompletionEvent* begin_main_frame_sent_completion,
-    ReadbackRequest* request) {
-  TRACE_EVENT0("cc", "ThreadProxy::ForceCommitForReadbackOnImplThread");
-  DCHECK(IsImplThread());
-  DCHECK(!impl().begin_main_frame_sent_completion_event);
-  DCHECK(!impl().readback_request);
-
-  if (!impl().layer_tree_host_impl) {
-    begin_main_frame_sent_completion->Signal();
-    request->success = false;
-    request->completion.Signal();
-    return;
-  }
-
-  impl().readback_request = request;
-
-  impl().scheduler->SetNeedsForcedCommitForReadback();
-  if (impl().scheduler->CommitPending()) {
-    begin_main_frame_sent_completion->Signal();
-    return;
-  }
-
-  impl().begin_main_frame_sent_completion_event =
-      begin_main_frame_sent_completion;
-}
-
 void ThreadProxy::FinishAllRendering() {
   DCHECK(Proxy::IsMainThread());
   DCHECK(!main().defer_commits);
@@ -274,79 +181,72 @@ void ThreadProxy::SetVisibleOnImplThread(CompletionEvent* completion,
 }
 
 void ThreadProxy::UpdateBackgroundAnimateTicking() {
-  impl().layer_tree_host_impl->UpdateBackgroundAnimateTicking(
+  bool should_background_tick =
       !impl().scheduler->WillDrawIfNeeded() &&
-      impl().layer_tree_host_impl->active_tree()->root_layer());
+      impl().layer_tree_host_impl->active_tree()->root_layer();
+  impl().layer_tree_host_impl->UpdateBackgroundAnimateTicking(
+      should_background_tick);
 }
 
-void ThreadProxy::DoCreateAndInitializeOutputSurface() {
-  TRACE_EVENT0("cc", "ThreadProxy::DoCreateAndInitializeOutputSurface");
+void ThreadProxy::DidLoseOutputSurface() {
+  TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurface");
   DCHECK(IsMainThread());
+  layer_tree_host()->DidLoseOutputSurface();
 
-  scoped_ptr<OutputSurface> output_surface =
-      layer_tree_host()->CreateOutputSurface();
+  {
+    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
 
-  RendererCapabilities capabilities;
-  bool success = !!output_surface;
-  if (!success) {
-    OnOutputSurfaceInitializeAttempted(false, capabilities);
-    return;
-  }
+    // Return lost resources to their owners immediately.
+    BlockingTaskRunner::CapturePostTasks blocked(
+        blocking_main_thread_task_runner());
 
-  scoped_refptr<ContextProvider> offscreen_context_provider;
-  if (main().created_offscreen_context_provider) {
-    offscreen_context_provider =
-        layer_tree_host()->client()->OffscreenContextProvider();
-    success = !!offscreen_context_provider.get();
-    if (!success) {
-      OnOutputSurfaceInitializeAttempted(false, capabilities);
-      return;
-    }
+    CompletionEvent completion;
+    Proxy::ImplThreadTaskRunner()->PostTask(
+        FROM_HERE,
+        base::Bind(&ThreadProxy::DeleteContentsTexturesOnImplThread,
+                   impl_thread_weak_ptr_,
+                   &completion));
+    completion.Wait();
   }
+}
 
-  success = false;
-  {
-    // Make a blocking call to InitializeOutputSurfaceOnImplThread. The results
-    // of that call are pushed into the success and capabilities local
-    // variables.
-    CompletionEvent completion;
-    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
+void ThreadProxy::RequestNewOutputSurface() {
+  DCHECK(IsMainThread());
+  layer_tree_host()->RequestNewOutputSurface();
+}
 
+void ThreadProxy::SetOutputSurface(scoped_ptr<OutputSurface> output_surface) {
+  if (output_surface) {
     Proxy::ImplThreadTaskRunner()->PostTask(
         FROM_HERE,
         base::Bind(&ThreadProxy::InitializeOutputSurfaceOnImplThread,
                    impl_thread_weak_ptr_,
-                   &completion,
-                   base::Passed(&output_surface),
-                   offscreen_context_provider,
-                   &success,
-                   &capabilities));
-    completion.Wait();
+                   base::Passed(&output_surface)));
+    return;
   }
 
-  OnOutputSurfaceInitializeAttempted(success, capabilities);
+  DidInitializeOutputSurface(false, RendererCapabilities());
 }
 
-void ThreadProxy::OnOutputSurfaceInitializeAttempted(
+void ThreadProxy::DidInitializeOutputSurface(
     bool success,
     const RendererCapabilities& capabilities) {
+  TRACE_EVENT0("cc", "ThreadProxy::DidInitializeOutputSurface");
   DCHECK(IsMainThread());
-  DCHECK(layer_tree_host());
+  main().renderer_capabilities_main_thread_copy = capabilities;
+  layer_tree_host()->OnCreateAndInitializeOutputSurfaceAttempted(success);
 
-  if (success) {
-    main().renderer_capabilities_main_thread_copy = capabilities;
+  if (!success) {
+    Proxy::MainThreadTaskRunner()->PostTask(
+        FROM_HERE,
+        base::Bind(&ThreadProxy::RequestNewOutputSurface,
+                   main_thread_weak_ptr_));
   }
+}
 
-  LayerTreeHost::CreateResult result =
-      layer_tree_host()->OnCreateAndInitializeOutputSurfaceAttempted(success);
-  if (result == LayerTreeHost::CreateFailedButTryAgain) {
-    if (!main().output_surface_creation_callback.callback().is_null()) {
-      Proxy::MainThreadTaskRunner()->PostTask(
-          FROM_HERE, main().output_surface_creation_callback.callback());
-    }
-  } else {
-    main().output_surface_creation_callback.Cancel();
-  }
+void ThreadProxy::SetRendererCapabilitiesMainThreadCopy(
+    const RendererCapabilities& capabilities) {
+  main().renderer_capabilities_main_thread_copy = capabilities;
 }
 
 void ThreadProxy::SendCommitRequestToImplThreadIfNeeded() {
@@ -373,7 +273,6 @@ void ThreadProxy::SetNeedsAnimate() {
 
   TRACE_EVENT0("cc", "ThreadProxy::SetNeedsAnimate");
   main().animate_requested = true;
-  main().can_cancel_commit = false;
   SendCommitRequestToImplThreadIfNeeded();
 }
 
@@ -400,53 +299,64 @@ void ThreadProxy::SetNeedsCommit() {
   SendCommitRequestToImplThreadIfNeeded();
 }
 
-void ThreadProxy::DidLoseOutputSurfaceOnImplThread() {
+void ThreadProxy::UpdateRendererCapabilitiesOnImplThread() {
   DCHECK(IsImplThread());
-  TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurfaceOnImplThread");
-  CheckOutputSurfaceStatusOnImplThread();
+  Proxy::MainThreadTaskRunner()->PostTask(
+      FROM_HERE,
+      base::Bind(&ThreadProxy::SetRendererCapabilitiesMainThreadCopy,
+                 main_thread_weak_ptr_,
+                 impl()
+                     .layer_tree_host_impl->GetRendererCapabilities()
+                     .MainThreadCapabilities()));
 }
 
-void ThreadProxy::CheckOutputSurfaceStatusOnImplThread() {
+void ThreadProxy::DidLoseOutputSurfaceOnImplThread() {
+  TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurfaceOnImplThread");
   DCHECK(IsImplThread());
-  TRACE_EVENT0("cc", "ThreadProxy::CheckOutputSurfaceStatusOnImplThread");
-  if (!impl().layer_tree_host_impl->IsContextLost())
-    return;
-  if (ContextProvider* offscreen_contexts =
-          impl().layer_tree_host_impl->offscreen_context_provider())
-    offscreen_contexts->VerifyContexts();
+  Proxy::MainThreadTaskRunner()->PostTask(
+      FROM_HERE,
+      base::Bind(&ThreadProxy::DidLoseOutputSurface, main_thread_weak_ptr_));
   impl().scheduler->DidLoseOutputSurface();
 }
 
-void ThreadProxy::OnSwapBuffersCompleteOnImplThread() {
+void ThreadProxy::CommitVSyncParameters(base::TimeTicks timebase,
+                                        base::TimeDelta interval) {
+  impl().scheduler->CommitVSyncParameters(timebase, interval);
+}
+
+void ThreadProxy::SetEstimatedParentDrawTime(base::TimeDelta draw_time) {
+  impl().scheduler->SetEstimatedParentDrawTime(draw_time);
+}
+
+void ThreadProxy::SetMaxSwapsPendingOnImplThread(int max) {
+  impl().scheduler->SetMaxSwapsPending(max);
+}
+
+void ThreadProxy::DidSwapBuffersOnImplThread() {
+  impl().scheduler->DidSwapBuffers();
+}
+
+void ThreadProxy::DidSwapBuffersCompleteOnImplThread() {
+  TRACE_EVENT0("cc", "ThreadProxy::DidSwapBuffersCompleteOnImplThread");
   DCHECK(IsImplThread());
-  TRACE_EVENT0("cc", "ThreadProxy::OnSwapBuffersCompleteOnImplThread");
+  impl().scheduler->DidSwapBuffersComplete();
   Proxy::MainThreadTaskRunner()->PostTask(
       FROM_HERE,
       base::Bind(&ThreadProxy::DidCompleteSwapBuffers, main_thread_weak_ptr_));
 }
 
-void ThreadProxy::SetNeedsBeginImplFrame(bool enable) {
-  DCHECK(IsImplThread());
-  TRACE_EVENT1("cc", "ThreadProxy::SetNeedsBeginImplFrame", "enable", enable);
-  impl().layer_tree_host_impl->SetNeedsBeginImplFrame(enable);
-  UpdateBackgroundAnimateTicking();
+BeginFrameSource* ThreadProxy::ExternalBeginFrameSource() {
+  return impl().layer_tree_host_impl.get();
 }
 
-void ThreadProxy::BeginImplFrame(const BeginFrameArgs& args) {
-  DCHECK(IsImplThread());
-  TRACE_EVENT0("cc", "ThreadProxy::BeginImplFrame");
-
-  // Sample the frame time now. This time will be used for updating animations
-  // when we draw.
-  impl().layer_tree_host_impl->CurrentFrameTimeTicks();
-
-  impl().scheduler->BeginImplFrame(args);
+void ThreadProxy::WillBeginImplFrame(const BeginFrameArgs& args) {
+  impl().layer_tree_host_impl->WillBeginImplFrame(args);
 }
 
 void ThreadProxy::OnCanDrawStateChanged(bool can_draw) {
-  DCHECK(IsImplThread());
   TRACE_EVENT1(
       "cc", "ThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw);
+  DCHECK(IsImplThread());
   impl().scheduler->SetCanDraw(can_draw);
   UpdateBackgroundAnimateTicking();
 }
@@ -457,23 +367,21 @@ void ThreadProxy::NotifyReadyToActivate() {
 }
 
 void ThreadProxy::SetNeedsCommitOnImplThread() {
-  DCHECK(IsImplThread());
   TRACE_EVENT0("cc", "ThreadProxy::SetNeedsCommitOnImplThread");
+  DCHECK(IsImplThread());
   impl().scheduler->SetNeedsCommit();
 }
 
 void ThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
-    scoped_ptr<AnimationEventsVector> events,
-    base::Time wall_clock_time) {
-  DCHECK(IsImplThread());
+    scoped_ptr<AnimationEventsVector> events) {
   TRACE_EVENT0("cc",
                "ThreadProxy::PostAnimationEventsToMainThreadOnImplThread");
+  DCHECK(IsImplThread());
   Proxy::MainThreadTaskRunner()->PostTask(
       FROM_HERE,
       base::Bind(&ThreadProxy::SetAnimationEvents,
                  main_thread_weak_ptr_,
-                 base::Passed(&events),
-                 wall_clock_time));
+                 base::Passed(&events)));
 }
 
 bool ThreadProxy::ReduceContentsTextureMemoryOnImplThread(size_t limit_bytes,
@@ -502,30 +410,11 @@ bool ThreadProxy::ReduceContentsTextureMemoryOnImplThread(size_t limit_bytes,
   return true;
 }
 
-void ThreadProxy::SendManagedMemoryStats() {
-  DCHECK(IsImplThread());
-  if (!impl().layer_tree_host_impl)
-    return;
-  if (!impl().contents_texture_manager)
-    return;
-
-  // If we are using impl-side painting, then SendManagedMemoryStats is called
-  // directly after the tile manager's manage function, and doesn't need to
-  // interact with main thread's layer tree.
-  if (impl().layer_tree_host_impl->settings().impl_side_painting)
-    return;
-
-  impl().layer_tree_host_impl->SendManagedMemoryStats(
-      impl().contents_texture_manager->MemoryVisibleBytes(),
-      impl().contents_texture_manager->MemoryVisibleAndNearbyBytes(),
-      impl().contents_texture_manager->MemoryUseBytes());
-}
-
 bool ThreadProxy::IsInsideDraw() { return impl().inside_draw; }
 
 void ThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) {
-  DCHECK(IsMainThread());
   TRACE_EVENT0("cc", "ThreadProxy::SetNeedsRedraw");
+  DCHECK(IsMainThread());
   Proxy::ImplThreadTaskRunner()->PostTask(
       FROM_HERE,
       base::Bind(&ThreadProxy::SetNeedsRedrawRectOnImplThread,
@@ -541,20 +430,22 @@ void ThreadProxy::SetNextCommitWaitsForActivation() {
 
 void ThreadProxy::SetDeferCommits(bool defer_commits) {
   DCHECK(IsMainThread());
-  DCHECK_NE(main().defer_commits, defer_commits);
-  main().defer_commits = defer_commits;
+  if (main().defer_commits == defer_commits)
+    return;
 
+  main().defer_commits = defer_commits;
   if (main().defer_commits)
     TRACE_EVENT_ASYNC_BEGIN0("cc", "ThreadProxy::SetDeferCommits", this);
   else
     TRACE_EVENT_ASYNC_END0("cc", "ThreadProxy::SetDeferCommits", this);
 
-  if (!main().defer_commits && main().pending_deferred_commit)
+  if (!main().defer_commits && main().pending_deferred_commit) {
     Proxy::MainThreadTaskRunner()->PostTask(
         FROM_HERE,
         base::Bind(&ThreadProxy::BeginMainFrame,
                    main_thread_weak_ptr_,
                    base::Passed(&main().pending_deferred_commit)));
+  }
 }
 
 bool ThreadProxy::CommitRequested() const {
@@ -568,11 +459,17 @@ bool ThreadProxy::BeginMainFrameRequested() const {
 }
 
 void ThreadProxy::SetNeedsRedrawOnImplThread() {
-  DCHECK(IsImplThread());
   TRACE_EVENT0("cc", "ThreadProxy::SetNeedsRedrawOnImplThread");
+  DCHECK(IsImplThread());
   impl().scheduler->SetNeedsRedraw();
 }
 
+void ThreadProxy::SetNeedsAnimateOnImplThread() {
+  TRACE_EVENT0("cc", "ThreadProxy::SetNeedsAnimateOnImplThread");
+  DCHECK(IsImplThread());
+  impl().scheduler->SetNeedsAnimate();
+}
+
 void ThreadProxy::SetNeedsManageTilesOnImplThread() {
   DCHECK(IsImplThread());
   impl().scheduler->SetNeedsManageTiles();
@@ -596,8 +493,8 @@ void ThreadProxy::SetSwapUsedIncompleteTileOnImplThread(
 }
 
 void ThreadProxy::DidInitializeVisibleTileOnImplThread() {
-  DCHECK(IsImplThread());
   TRACE_EVENT0("cc", "ThreadProxy::DidInitializeVisibleTileOnImplThread");
+  DCHECK(IsImplThread());
   impl().scheduler->SetNeedsRedraw();
 }
 
@@ -680,8 +577,7 @@ void ThreadProxy::Start() {
       FROM_HERE,
       base::Bind(&ThreadProxy::InitializeImplOnImplThread,
                  base::Unretained(this),
-                 &completion,
-                 main().layer_tree_host_id));
+                 &completion));
   completion.Wait();
 
   main_thread_weak_ptr_ = main().weak_factory.GetWeakPtr();
@@ -744,6 +640,24 @@ void ThreadProxy::ForceSerializeOnSwapBuffersOnImplThread(
   completion->Signal();
 }
 
+bool ThreadProxy::SupportsImplScrolling() const {
+  return true;
+}
+
+void ThreadProxy::SetDebugState(const LayerTreeDebugState& debug_state) {
+  Proxy::ImplThreadTaskRunner()->PostTask(
+      FROM_HERE,
+      base::Bind(&ThreadProxy::SetDebugStateOnImplThread,
+                 impl_thread_weak_ptr_,
+                 debug_state));
+}
+
+void ThreadProxy::SetDebugStateOnImplThread(
+    const LayerTreeDebugState& debug_state) {
+  DCHECK(IsImplThread());
+  impl().scheduler->SetContinuousPainting(debug_state.continuous_painting);
+}
+
 void ThreadProxy::FinishAllRenderingOnImplThread(CompletionEvent* completion) {
   TRACE_EVENT0("cc", "ThreadProxy::FinishAllRenderingOnImplThread");
   DCHECK(IsImplThread());
@@ -752,11 +666,14 @@ void ThreadProxy::FinishAllRenderingOnImplThread(CompletionEvent* completion) {
 }
 
 void ThreadProxy::ScheduledActionSendBeginMainFrame() {
-  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionSendBeginMainFrame");
+  unsigned int begin_frame_id = nextBeginFrameId++;
+  benchmark_instrumentation::ScopedBeginFrameTask begin_frame_task(
+      benchmark_instrumentation::kSendBeginFrame, begin_frame_id);
   scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state(
       new BeginMainFrameAndCommitState);
-  begin_main_frame_state->monotonic_frame_begin_time =
-      impl().layer_tree_host_impl->CurrentPhysicalTimeTicks();
+  begin_main_frame_state->begin_frame_id = begin_frame_id;
+  begin_main_frame_state->begin_frame_args =
+      impl().layer_tree_host_impl->CurrentBeginFrameArgs();
   begin_main_frame_state->scroll_info =
       impl().layer_tree_host_impl->ProcessScrollDeltas();
 
@@ -774,53 +691,38 @@ void ThreadProxy::ScheduledActionSendBeginMainFrame() {
       base::Bind(&ThreadProxy::BeginMainFrame,
                  main_thread_weak_ptr_,
                  base::Passed(&begin_main_frame_state)));
-
-  if (impl().begin_main_frame_sent_completion_event) {
-    impl().begin_main_frame_sent_completion_event->Signal();
-    impl().begin_main_frame_sent_completion_event = NULL;
-  }
-  impl().begin_main_frame_sent_time = base::TimeTicks::HighResNow();
+  devtools_instrumentation::DidRequestMainThreadFrame(
+      impl().layer_tree_host_id);
+  impl().timing_history.DidBeginMainFrame();
 }
 
 void ThreadProxy::BeginMainFrame(
     scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state) {
-  TRACE_EVENT0("cc", "ThreadProxy::BeginMainFrame");
+  benchmark_instrumentation::ScopedBeginFrameTask begin_frame_task(
+      benchmark_instrumentation::kDoBeginFrame,
+      begin_main_frame_state->begin_frame_id);
   TRACE_EVENT_SYNTHETIC_DELAY_BEGIN("cc.BeginMainFrame");
   DCHECK(IsMainThread());
 
-  if (!layer_tree_host())
-    return;
-
   if (main().defer_commits) {
     main().pending_deferred_commit = begin_main_frame_state.Pass();
     layer_tree_host()->DidDeferCommit();
-    TRACE_EVENT0("cc", "EarlyOut_DeferCommits");
+    TRACE_EVENT_INSTANT0(
+        "cc", "EarlyOut_DeferCommits", TRACE_EVENT_SCOPE_THREAD);
     return;
   }
 
   // If the commit finishes, LayerTreeHost will transfer its swap promises to
-  // LayerTreeImpl. The destructor of SwapPromiseChecker checks LayerTressHost's
-  // swap promises.
-  SwapPromiseChecker swap_promise_checker(layer_tree_host());
-
-  // Do not notify the impl thread of commit requests that occur during
-  // the apply/animate/layout part of the BeginMainFrameAndCommit process since
-  // those commit requests will get painted immediately. Once we have done
-  // the paint, main().commit_requested will be set to false to allow new commit
-  // requests to be scheduled.
-  main().commit_requested = true;
-  main().commit_request_sent_to_impl_thread = true;
+  // LayerTreeImpl. The destructor of ScopedSwapPromiseChecker aborts the
+  // remaining swap promises.
+  ScopedAbortRemainingSwapPromises swap_promise_checker(layer_tree_host());
 
-  // On the other hand, the AnimationRequested flag needs to be cleared
-  // here so that any animation requests generated by the apply or animate
-  // callbacks will trigger another frame.
+  main().commit_requested = false;
+  main().commit_request_sent_to_impl_thread = false;
   main().animate_requested = false;
 
-  if (!main().in_composite_and_readback && !layer_tree_host()->visible()) {
-    main().commit_requested = false;
-    main().commit_request_sent_to_impl_thread = false;
-
-    TRACE_EVENT0("cc", "EarlyOut_NotVisible");
+  if (!layer_tree_host()->visible()) {
+    TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD);
     bool did_handle = false;
     Proxy::ImplThreadTaskRunner()->PostTask(
         FROM_HERE,
@@ -830,39 +732,52 @@ void ThreadProxy::BeginMainFrame(
     return;
   }
 
-  if (begin_main_frame_state) {
-    layer_tree_host()->ApplyScrollAndScale(
-        *begin_main_frame_state->scroll_info);
+  if (layer_tree_host()->output_surface_lost()) {
+    TRACE_EVENT_INSTANT0(
+        "cc", "EarlyOut_OutputSurfaceLost", TRACE_EVENT_SCOPE_THREAD);
+    bool did_handle = false;
+    Proxy::ImplThreadTaskRunner()->PostTask(
+        FROM_HERE,
+        base::Bind(&ThreadProxy::BeginMainFrameAbortedOnImplThread,
+                   impl_thread_weak_ptr_,
+                   did_handle));
+    return;
   }
 
+  // Do not notify the impl thread of commit requests that occur during
+  // the apply/animate/layout part of the BeginMainFrameAndCommit process since
+  // those commit requests will get painted immediately. Once we have done
+  // the paint, main().commit_requested will be set to false to allow new commit
+  // requests to be scheduled.
+  // On the other hand, the animate_requested flag should remain cleared
+  // here so that any animation requests generated by the apply or animate
+  // callbacks will trigger another frame.
+  main().commit_requested = true;
+  main().commit_request_sent_to_impl_thread = true;
+
+  layer_tree_host()->ApplyScrollAndScale(
+      begin_main_frame_state->scroll_info.get());
+
   layer_tree_host()->WillBeginMainFrame();
 
-  if (begin_main_frame_state) {
-    layer_tree_host()->UpdateClientAnimations(
-        begin_main_frame_state->monotonic_frame_begin_time);
-    layer_tree_host()->AnimateLayers(
-        begin_main_frame_state->monotonic_frame_begin_time);
-  }
+  layer_tree_host()->BeginMainFrame(begin_main_frame_state->begin_frame_args);
+  layer_tree_host()->AnimateLayers(
+      begin_main_frame_state->begin_frame_args.frame_time);
 
   // Unlink any backings that the impl thread has evicted, so that we know to
   // re-paint them in UpdateLayers.
   if (blocked_main().contents_texture_manager()) {
     blocked_main().contents_texture_manager()->UnlinkAndClearEvictedBackings();
 
-    if (begin_main_frame_state) {
-      blocked_main().contents_texture_manager()->SetMaxMemoryLimitBytes(
-          begin_main_frame_state->memory_allocation_limit_bytes);
-      blocked_main().contents_texture_manager()->SetExternalPriorityCutoff(
-          begin_main_frame_state->memory_allocation_priority_cutoff);
-    }
+    blocked_main().contents_texture_manager()->SetMaxMemoryLimitBytes(
+        begin_main_frame_state->memory_allocation_limit_bytes);
+    blocked_main().contents_texture_manager()->SetExternalPriorityCutoff(
+        begin_main_frame_state->memory_allocation_priority_cutoff);
   }
 
   // Recreate all UI resources if there were evicted UI resources when the impl
   // thread initiated the commit.
-  bool evicted_ui_resources = begin_main_frame_state
-                                  ? begin_main_frame_state->evicted_ui_resources
-                                  : false;
-  if (evicted_ui_resources)
+  if (begin_main_frame_state->evicted_ui_resources)
     layer_tree_host()->RecreateUIResources();
 
   layer_tree_host()->Layout();
@@ -873,9 +788,8 @@ void ThreadProxy::BeginMainFrame(
   // UpdateLayers.
   main().commit_requested = false;
   main().commit_request_sent_to_impl_thread = false;
-  bool can_cancel_this_commit = main().can_cancel_commit &&
-                                !main().in_composite_and_readback &&
-                                !evicted_ui_resources;
+  bool can_cancel_this_commit =
+      main().can_cancel_commit && !begin_main_frame_state->evicted_ui_resources;
   main().can_cancel_commit = true;
 
   scoped_ptr<ResourceUpdateQueue> queue =
@@ -883,14 +797,21 @@ void ThreadProxy::BeginMainFrame(
 
   bool updated = layer_tree_host()->UpdateLayers(queue.get());
 
-  // Once single buffered layers are committed, they cannot be modified until
-  // they are drawn by the impl thread.
-  main().textures_acquired = false;
-
   layer_tree_host()->WillCommit();
 
+  // Before calling animate, we set main().animate_requested to false. If it is
+  // true now, it means SetNeedAnimate was called again, but during a state when
+  // main().commit_request_sent_to_impl_thread = true. We need to force that
+  // call to happen again now so that the commit request is sent to the impl
+  // thread.
+  if (main().animate_requested) {
+    // Forces SetNeedsAnimate to consider posting a commit task.
+    main().animate_requested = false;
+    SetNeedsAnimate();
+  }
+
   if (!updated && can_cancel_this_commit) {
-    TRACE_EVENT0("cc", "EarlyOut_NoUpdates");
+    TRACE_EVENT_INSTANT0("cc", "EarlyOut_NoUpdates", TRACE_EVENT_SCOPE_THREAD);
     bool did_handle = true;
     Proxy::ImplThreadTaskRunner()->PostTask(
         FROM_HERE,
@@ -903,30 +824,10 @@ void ThreadProxy::BeginMainFrame(
     // went through, and input should no longer be throttled, etc.
     layer_tree_host()->CommitComplete();
     layer_tree_host()->DidBeginMainFrame();
+    layer_tree_host()->BreakSwapPromises(SwapPromise::COMMIT_NO_UPDATE);
     return;
   }
 
-  // Before calling animate, we set main().animate_requested to false. If it is
-  // true
-  // now, it means SetNeedAnimate was called again, but during a state when
-  // main().commit_request_sent_to_impl_thread = true. We need to force that
-  // call to
-  // happen again now so that the commit request is sent to the impl thread.
-  if (main().animate_requested) {
-    // Forces SetNeedsAnimate to consider posting a commit task.
-    main().animate_requested = false;
-    SetNeedsAnimate();
-  }
-
-  scoped_refptr<ContextProvider> offscreen_context_provider;
-  if (main().renderer_capabilities_main_thread_copy.using_offscreen_context3d &&
-      layer_tree_host()->needs_offscreen_context()) {
-    offscreen_context_provider =
-        layer_tree_host()->client()->OffscreenContextProvider();
-    if (offscreen_context_provider.get())
-      main().created_offscreen_context_provider = true;
-  }
-
   // Notify the impl thread that the main thread is ready to commit. This will
   // begin the commit process, which is blocking from the main thread's
   // point of view, but asynchronously performed on the impl thread,
@@ -939,7 +840,8 @@ void ThreadProxy::BeginMainFrame(
     // This CapturePostTasks should be destroyed before CommitComplete() is
     // called since that goes out to the embedder, and we want the embedder
     // to receive its callbacks before that.
-    BlockingTaskRunner::CapturePostTasks blocked;
+    BlockingTaskRunner::CapturePostTasks blocked(
+        blocking_main_thread_task_runner());
 
     CompletionEvent completion;
     Proxy::ImplThreadTaskRunner()->PostTask(
@@ -947,13 +849,12 @@ void ThreadProxy::BeginMainFrame(
         base::Bind(&ThreadProxy::StartCommitOnImplThread,
                    impl_thread_weak_ptr_,
                    &completion,
-                   queue.release(),
-                   offscreen_context_provider));
+                   queue.release()));
     completion.Wait();
 
     RenderingStatsInstrumentation* stats_instrumentation =
         layer_tree_host()->rendering_stats_instrumentation();
-    BenchmarkInstrumentation::IssueMainThreadRenderingStatsEvent(
+    benchmark_instrumentation::IssueMainThreadRenderingStatsEvent(
         stats_instrumentation->main_thread_rendering_stats());
     stats_instrumentation->AccumulateAndClearMainThreadStats();
   }
@@ -962,12 +863,8 @@ void ThreadProxy::BeginMainFrame(
   layer_tree_host()->DidBeginMainFrame();
 }
 
-void ThreadProxy::StartCommitOnImplThread(
-    CompletionEvent* completion,
-    ResourceUpdateQueue* raw_queue,
-    scoped_refptr<ContextProvider> offscreen_context_provider) {
-  scoped_ptr<ResourceUpdateQueue> queue(raw_queue);
-
+void ThreadProxy::StartCommitOnImplThread(CompletionEvent* completion,
+                                          ResourceUpdateQueue* raw_queue) {
   TRACE_EVENT0("cc", "ThreadProxy::StartCommitOnImplThread");
   DCHECK(!impl().commit_completion_event);
   DCHECK(IsImplThread() && IsMainThreadBlocked());
@@ -975,15 +872,17 @@ void ThreadProxy::StartCommitOnImplThread(
   DCHECK(impl().scheduler->CommitPending());
 
   if (!impl().layer_tree_host_impl) {
-    TRACE_EVENT0("cc", "EarlyOut_NoLayerTree");
+    TRACE_EVENT_INSTANT0(
+        "cc", "EarlyOut_NoLayerTree", TRACE_EVENT_SCOPE_THREAD);
     completion->Signal();
     return;
   }
 
-  if (offscreen_context_provider.get())
-    offscreen_context_provider->BindToCurrentThread();
-  impl().layer_tree_host_impl->SetOffscreenContextProvider(
-      offscreen_context_provider);
+  // Ideally, we should inform to impl thread when BeginMainFrame is started.
+  // But, we can avoid a PostTask in here.
+  impl().scheduler->NotifyBeginMainFrameStarted();
+
+  scoped_ptr<ResourceUpdateQueue> queue(raw_queue);
 
   if (impl().contents_texture_manager) {
     DCHECK_EQ(impl().contents_texture_manager,
@@ -1030,6 +929,15 @@ void ThreadProxy::BeginMainFrameAbortedOnImplThread(bool did_handle) {
   impl().scheduler->BeginMainFrameAborted(did_handle);
 }
 
+void ThreadProxy::ScheduledActionAnimate() {
+  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionAnimate");
+  DCHECK(IsImplThread());
+
+  impl().animation_time =
+      impl().layer_tree_host_impl->CurrentBeginFrameArgs().frame_time;
+  impl().layer_tree_host_impl->Animate(impl().animation_time);
+}
+
 void ThreadProxy::ScheduledActionCommit() {
   TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionCommit");
   DCHECK(IsImplThread());
@@ -1039,7 +947,7 @@ void ThreadProxy::ScheduledActionCommit() {
 
   // Complete all remaining texture updates.
   impl().current_resource_update_controller->Finalize();
-  impl().current_resource_update_controller.reset();
+  impl().current_resource_update_controller = nullptr;
 
   blocked_main().main_thread_inside_commit = true;
   impl().layer_tree_host_impl->BeginCommit();
@@ -1054,8 +962,8 @@ void ThreadProxy::ScheduledActionCommit() {
 
   if (hold_commit) {
     // For some layer types in impl-side painting, the commit is held until
-    // the pending tree is activated.  It's also possible that the
-    // pending tree has already activated if there was no work to be done.
+    // the sync tree is activated.  It's also possible that the
+    // sync tree has already activated if there was no work to be done.
     TRACE_EVENT_INSTANT0("cc", "HoldCommit", TRACE_EVENT_SCOPE_THREAD);
     impl().completion_event_for_commit_held_on_tree_activation =
         impl().commit_completion_event;
@@ -1075,66 +983,41 @@ void ThreadProxy::ScheduledActionCommit() {
 
   impl().next_frame_is_newly_committed_frame = true;
 
-  impl().commit_complete_time = base::TimeTicks::HighResNow();
-  impl().begin_main_frame_to_commit_duration_history.InsertSample(
-      impl().commit_complete_time - impl().begin_main_frame_sent_time);
-
-  // SetVisible kicks off the next scheduler action, so this must be last.
-  impl().scheduler->SetVisible(impl().layer_tree_host_impl->visible());
+  impl().timing_history.DidCommit();
 }
 
 void ThreadProxy::ScheduledActionUpdateVisibleTiles() {
-  DCHECK(IsImplThread());
   TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionUpdateVisibleTiles");
+  DCHECK(IsImplThread());
   impl().layer_tree_host_impl->UpdateVisibleTiles();
 }
 
-void ThreadProxy::ScheduledActionActivatePendingTree() {
+void ThreadProxy::ScheduledActionActivateSyncTree() {
+  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionActivateSyncTree");
   DCHECK(IsImplThread());
-  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionActivatePendingTree");
-  impl().layer_tree_host_impl->ActivatePendingTree();
+  impl().layer_tree_host_impl->ActivateSyncTree();
 }
 
 void ThreadProxy::ScheduledActionBeginOutputSurfaceCreation() {
-  DCHECK(IsImplThread());
   TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionBeginOutputSurfaceCreation");
+  DCHECK(IsImplThread());
   Proxy::MainThreadTaskRunner()->PostTask(
       FROM_HERE,
-      base::Bind(&ThreadProxy::CreateAndInitializeOutputSurface,
-                 main_thread_weak_ptr_));
+      base::Bind(&ThreadProxy::RequestNewOutputSurface, main_thread_weak_ptr_));
 }
 
-DrawSwapReadbackResult ThreadProxy::DrawSwapReadbackInternal(
-    bool forced_draw,
-    bool swap_requested,
-    bool readback_requested) {
+DrawResult ThreadProxy::DrawSwapInternal(bool forced_draw) {
   TRACE_EVENT_SYNTHETIC_DELAY("cc.DrawAndSwap");
-  DrawSwapReadbackResult result;
-  result.did_draw = false;
-  result.did_swap = false;
-  result.did_readback = false;
+  DrawResult result;
+
   DCHECK(IsImplThread());
   DCHECK(impl().layer_tree_host_impl.get());
-  if (!impl().layer_tree_host_impl)
-    return result;
-
-  DCHECK(impl().layer_tree_host_impl->renderer());
-  if (!impl().layer_tree_host_impl->renderer())
-    return result;
 
-  base::TimeTicks start_time = base::TimeTicks::HighResNow();
-  base::TimeDelta draw_duration_estimate = DrawDurationEstimate();
+  impl().timing_history.DidStartDrawing();
   base::AutoReset<bool> mark_inside(&impl().inside_draw, true);
 
-  // Advance our animations.
-  base::TimeTicks monotonic_time =
-      impl().layer_tree_host_impl->CurrentFrameTimeTicks();
-  base::Time wall_clock_time = impl().layer_tree_host_impl->CurrentFrameTime();
-
-  // TODO(enne): This should probably happen post-animate.
   if (impl().layer_tree_host_impl->pending_tree())
     impl().layer_tree_host_impl->pending_tree()->UpdateDrawProperties();
-  impl().layer_tree_host_impl->Animate(monotonic_time, wall_clock_time);
 
   // This method is called on a forced draw, regardless of whether we are able
   // to produce a frame, as the calling site on main thread is blocked until its
@@ -1147,53 +1030,33 @@ DrawSwapReadbackResult ThreadProxy::DrawSwapReadbackInternal(
   // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
   // CanDraw() as well.
 
-  bool drawing_for_readback = readback_requested && !!impl().readback_request;
-  bool can_do_readback =
-      impl().layer_tree_host_impl->renderer()->CanReadPixels();
-
   LayerTreeHostImpl::FrameData frame;
   bool draw_frame = false;
 
-  if (impl().layer_tree_host_impl->CanDraw() &&
-      (!drawing_for_readback || can_do_readback)) {
-    // If it is for a readback, make sure we draw the portion being read back.
-    gfx::Rect readback_rect;
-    if (drawing_for_readback)
-      readback_rect = impl().readback_request->rect;
-
-    if (impl().layer_tree_host_impl->PrepareToDraw(&frame, readback_rect) ||
-        forced_draw)
-      draw_frame = true;
+  if (impl().layer_tree_host_impl->CanDraw()) {
+    result = impl().layer_tree_host_impl->PrepareToDraw(&frame);
+    draw_frame = forced_draw || result == DRAW_SUCCESS;
+  } else {
+    result = DRAW_ABORTED_CANT_DRAW;
   }
 
   if (draw_frame) {
     impl().layer_tree_host_impl->DrawLayers(
         &frame, impl().scheduler->LastBeginImplFrameTime());
-    result.did_draw = true;
+    result = DRAW_SUCCESS;
+  } else {
+    DCHECK_NE(DRAW_SUCCESS, result);
   }
   impl().layer_tree_host_impl->DidDrawAllLayers(frame);
 
   bool start_ready_animations = draw_frame;
   impl().layer_tree_host_impl->UpdateAnimationState(start_ready_animations);
 
-  // Check for a pending CompositeAndReadback.
-  if (drawing_for_readback) {
-    DCHECK(!swap_requested);
-    result.did_readback = false;
-    if (draw_frame && !impl().layer_tree_host_impl->IsContextLost()) {
-      impl().layer_tree_host_impl->Readback(impl().readback_request->pixels,
-                                            impl().readback_request->rect);
-      result.did_readback = true;
-    }
-    impl().readback_request->success = result.did_readback;
-    impl().readback_request->completion.Signal();
-    impl().readback_request = NULL;
-  } else if (draw_frame) {
-    DCHECK(swap_requested);
-    result.did_swap = impl().layer_tree_host_impl->SwapBuffers(frame);
+  if (draw_frame) {
+    bool did_request_swap = impl().layer_tree_host_impl->SwapBuffers(frame);
 
     // We don't know if we have incomplete tiles if we didn't actually swap.
-    if (result.did_swap) {
+    if (did_request_swap) {
       DCHECK(!frame.has_no_damage);
       SetSwapUsedIncompleteTileOnImplThread(frame.contains_incomplete_tile);
     }
@@ -1207,109 +1070,35 @@ DrawSwapReadbackResult ThreadProxy::DrawSwapReadbackInternal(
         base::Bind(&ThreadProxy::DidCommitAndDrawFrame, main_thread_weak_ptr_));
   }
 
-  if (draw_frame) {
-    CheckOutputSurfaceStatusOnImplThread();
-
-    base::TimeDelta draw_duration = base::TimeTicks::HighResNow() - start_time;
-    impl().draw_duration_history.InsertSample(draw_duration);
-    base::TimeDelta draw_duration_overestimate;
-    base::TimeDelta draw_duration_underestimate;
-    if (draw_duration > draw_duration_estimate)
-      draw_duration_underestimate = draw_duration - draw_duration_estimate;
-    else
-      draw_duration_overestimate = draw_duration_estimate - draw_duration;
-    UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDuration",
-                               draw_duration,
-                               base::TimeDelta::FromMilliseconds(1),
-                               base::TimeDelta::FromMilliseconds(100),
-                               50);
-    UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDurationUnderestimate",
-                               draw_duration_underestimate,
-                               base::TimeDelta::FromMilliseconds(1),
-                               base::TimeDelta::FromMilliseconds(100),
-                               50);
-    UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDurationOverestimate",
-                               draw_duration_overestimate,
-                               base::TimeDelta::FromMilliseconds(1),
-                               base::TimeDelta::FromMilliseconds(100),
-                               50);
-  }
+  if (result == DRAW_SUCCESS)
+    impl().timing_history.DidFinishDrawing();
 
+  DCHECK_NE(INVALID_RESULT, result);
   return result;
 }
 
-void ThreadProxy::AcquireLayerTextures() {
-  // Called when the main thread needs to modify a layer texture that is used
-  // directly by the compositor.
-  // This method will block until the next compositor draw if there is a
-  // previously committed frame that is still undrawn. This is necessary to
-  // ensure that the main thread does not monopolize access to the textures.
-  DCHECK(IsMainThread());
-
-  if (main().textures_acquired)
-    return;
-
-  TRACE_EVENT0("cc", "ThreadProxy::AcquireLayerTextures");
-  DebugScopedSetMainThreadBlocked main_thread_blocked(this);
-  CompletionEvent completion;
-  Proxy::ImplThreadTaskRunner()->PostTask(
-      FROM_HERE,
-      base::Bind(&ThreadProxy::AcquireLayerTexturesForMainThreadOnImplThread,
-                 impl_thread_weak_ptr_,
-                 &completion));
-  // Block until it is safe to write to layer textures from the main thread.
-  completion.Wait();
-
-  main().textures_acquired = true;
-  main().can_cancel_commit = false;
-}
-
-void ThreadProxy::AcquireLayerTexturesForMainThreadOnImplThread(
-    CompletionEvent* completion) {
-  DCHECK(IsImplThread());
-  DCHECK(!impl().texture_acquisition_completion_event);
-
-  impl().texture_acquisition_completion_event = completion;
-  impl().scheduler->SetMainThreadNeedsLayerTextures();
-}
-
-void ThreadProxy::ScheduledActionAcquireLayerTexturesForMainThread() {
-  DCHECK(impl().texture_acquisition_completion_event);
-  impl().texture_acquisition_completion_event->Signal();
-  impl().texture_acquisition_completion_event = NULL;
-}
-
 void ThreadProxy::ScheduledActionManageTiles() {
   TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionManageTiles");
   DCHECK(impl().layer_tree_host_impl->settings().impl_side_painting);
   impl().layer_tree_host_impl->ManageTiles();
 }
 
-DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndSwapIfPossible() {
+DrawResult ThreadProxy::ScheduledActionDrawAndSwapIfPossible() {
   TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndSwap");
+
+  // SchedulerStateMachine::DidDrawIfPossibleCompleted isn't set up to
+  // handle DRAW_ABORTED_CANT_DRAW.  Moreover, the scheduler should
+  // never generate this call when it can't draw.
+  DCHECK(impl().layer_tree_host_impl->CanDraw());
+
   bool forced_draw = false;
-  bool swap_requested = true;
-  bool readback_requested = false;
-  return DrawSwapReadbackInternal(
-      forced_draw, swap_requested, readback_requested);
+  return DrawSwapInternal(forced_draw);
 }
 
-DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndSwapForced() {
+DrawResult ThreadProxy::ScheduledActionDrawAndSwapForced() {
   TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndSwapForced");
   bool forced_draw = true;
-  bool swap_requested = true;
-  bool readback_requested = false;
-  return DrawSwapReadbackInternal(
-      forced_draw, swap_requested, readback_requested);
-}
-
-DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndReadback() {
-  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndReadback");
-  bool forced_draw = true;
-  bool swap_requested = false;
-  bool readback_requested = true;
-  return DrawSwapReadbackInternal(
-      forced_draw, swap_requested, readback_requested);
+  return DrawSwapInternal(forced_draw);
 }
 
 void ThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) {
@@ -1318,179 +1107,120 @@ void ThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) {
 }
 
 base::TimeDelta ThreadProxy::DrawDurationEstimate() {
-  base::TimeDelta historical_estimate = impl().draw_duration_history.Percentile(
-      kDrawDurationEstimationPercentile);
-  base::TimeDelta padding = base::TimeDelta::FromMicroseconds(
-      kDrawDurationEstimatePaddingInMicroseconds);
-  return historical_estimate + padding;
+  return impl().timing_history.DrawDurationEstimate();
 }
 
 base::TimeDelta ThreadProxy::BeginMainFrameToCommitDurationEstimate() {
-  return impl().begin_main_frame_to_commit_duration_history.Percentile(
-      kCommitAndActivationDurationEstimationPercentile);
+  return impl().timing_history.BeginMainFrameToCommitDurationEstimate();
 }
 
 base::TimeDelta ThreadProxy::CommitToActivateDurationEstimate() {
-  return impl().commit_to_activate_duration_history.Percentile(
-      kCommitAndActivationDurationEstimationPercentile);
-}
-
-void ThreadProxy::PostBeginImplFrameDeadline(const base::Closure& closure,
-                                             base::TimeTicks deadline) {
-  base::TimeDelta delta = deadline - gfx::FrameTime::Now();
-  if (delta <= base::TimeDelta())
-    delta = base::TimeDelta();
-  Proxy::ImplThreadTaskRunner()->PostDelayedTask(FROM_HERE, closure, delta);
+  return impl().timing_history.CommitToActivateDurationEstimate();
 }
 
 void ThreadProxy::DidBeginImplFrameDeadline() {
-  impl().layer_tree_host_impl->ResetCurrentFrameTimeForNextFrame();
+  impl().layer_tree_host_impl->ResetCurrentBeginFrameArgsForNextFrame();
 }
 
 void ThreadProxy::ReadyToFinalizeTextureUpdates() {
   DCHECK(IsImplThread());
-  impl().scheduler->FinishCommit();
+  impl().scheduler->NotifyReadyToCommit();
 }
 
 void ThreadProxy::DidCommitAndDrawFrame() {
   DCHECK(IsMainThread());
-  if (!layer_tree_host())
-    return;
   layer_tree_host()->DidCommitAndDrawFrame();
 }
 
 void ThreadProxy::DidCompleteSwapBuffers() {
   DCHECK(IsMainThread());
-  if (!layer_tree_host())
-    return;
   layer_tree_host()->DidCompleteSwapBuffers();
 }
 
-void ThreadProxy::SetAnimationEvents(scoped_ptr<AnimationEventsVector> events,
-                                     base::Time wall_clock_time) {
+void ThreadProxy::SetAnimationEvents(scoped_ptr<AnimationEventsVector> events) {
   TRACE_EVENT0("cc", "ThreadProxy::SetAnimationEvents");
   DCHECK(IsMainThread());
-  if (!layer_tree_host())
-    return;
-  layer_tree_host()->SetAnimationEvents(events.Pass(), wall_clock_time);
-}
-
-void ThreadProxy::CreateAndInitializeOutputSurface() {
-  TRACE_EVENT0("cc", "ThreadProxy::CreateAndInitializeOutputSurface");
-  DCHECK(IsMainThread());
-
-  // Check that output surface has not been recreated by CompositeAndReadback
-  // after this task is posted but before it is run.
-  bool has_initialized_output_surface = true;
-  {
-    CompletionEvent completion;
-    Proxy::ImplThreadTaskRunner()->PostTask(
-        FROM_HERE,
-        base::Bind(&ThreadProxy::HasInitializedOutputSurfaceOnImplThread,
-                   impl_thread_weak_ptr_,
-                   &completion,
-                   &has_initialized_output_surface));
-    completion.Wait();
-  }
-  if (has_initialized_output_surface)
-    return;
-
-  layer_tree_host()->DidLoseOutputSurface();
-  main().output_surface_creation_callback.Reset(
-      base::Bind(&ThreadProxy::DoCreateAndInitializeOutputSurface,
-                 base::Unretained(this)));
-  main().output_surface_creation_callback.callback().Run();
+  layer_tree_host()->SetAnimationEvents(events.Pass());
 }
 
-void ThreadProxy::HasInitializedOutputSurfaceOnImplThread(
-    CompletionEvent* completion,
-    bool* has_initialized_output_surface) {
-  DCHECK(IsImplThread());
-  *has_initialized_output_surface =
-      impl().scheduler->HasInitializedOutputSurface();
-  completion->Signal();
-}
-
-void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion,
-                                             int layer_tree_host_id) {
+void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) {
   TRACE_EVENT0("cc", "ThreadProxy::InitializeImplOnImplThread");
   DCHECK(IsImplThread());
   impl().layer_tree_host_impl =
       layer_tree_host()->CreateLayerTreeHostImpl(this);
-  const LayerTreeSettings& settings = layer_tree_host()->settings();
-  SchedulerSettings scheduler_settings;
-  scheduler_settings.deadline_scheduling_enabled =
-      settings.deadline_scheduling_enabled;
-  scheduler_settings.impl_side_painting = settings.impl_side_painting;
-  scheduler_settings.timeout_and_draw_when_animation_checkerboards =
-      settings.timeout_and_draw_when_animation_checkerboards;
-  scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ =
-      settings.maximum_number_of_failed_draws_before_draw_is_forced_;
-  scheduler_settings.using_synchronous_renderer_compositor =
-      settings.using_synchronous_renderer_compositor;
-  scheduler_settings.throttle_frame_production =
-      settings.throttle_frame_production;
-  impl().scheduler =
-      Scheduler::Create(this, scheduler_settings, layer_tree_host_id);
+  SchedulerSettings scheduler_settings(layer_tree_host()->settings());
+  impl().scheduler = Scheduler::Create(this,
+                                       scheduler_settings,
+                                       impl().layer_tree_host_id,
+                                       ImplThreadTaskRunner(),
+                                       base::PowerMonitor::Get());
   impl().scheduler->SetVisible(impl().layer_tree_host_impl->visible());
 
   impl_thread_weak_ptr_ = impl().weak_factory.GetWeakPtr();
   completion->Signal();
 }
 
-void ThreadProxy::InitializeOutputSurfaceOnImplThread(
-    CompletionEvent* completion,
-    scoped_ptr<OutputSurface> output_surface,
-    scoped_refptr<ContextProvider> offscreen_context_provider,
-    bool* success,
-    RendererCapabilities* capabilities) {
-  TRACE_EVENT0("cc", "ThreadProxy::InitializeOutputSurfaceOnImplThread");
+void ThreadProxy::DeleteContentsTexturesOnImplThread(
+    CompletionEvent* completion) {
+  TRACE_EVENT0("cc", "ThreadProxy::DeleteContentsTexturesOnImplThread");
   DCHECK(IsImplThread());
   DCHECK(IsMainThreadBlocked());
-  DCHECK(success);
-  DCHECK(capabilities);
-
   layer_tree_host()->DeleteContentsTexturesOnImplThread(
       impl().layer_tree_host_impl->resource_provider());
+  completion->Signal();
+}
 
-  *success =
-      impl().layer_tree_host_impl->InitializeRenderer(output_surface.Pass());
+void ThreadProxy::InitializeOutputSurfaceOnImplThread(
+    scoped_ptr<OutputSurface> output_surface) {
+  TRACE_EVENT0("cc", "ThreadProxy::InitializeOutputSurfaceOnImplThread");
+  DCHECK(IsImplThread());
 
-  if (*success) {
-    *capabilities = impl()
-                        .layer_tree_host_impl->GetRendererCapabilities()
-                        .MainThreadCapabilities();
-    impl().scheduler->DidCreateAndInitializeOutputSurface();
-  } else if (offscreen_context_provider.get()) {
-    if (offscreen_context_provider->BindToCurrentThread())
-      offscreen_context_provider->VerifyContexts();
-    offscreen_context_provider = NULL;
+  LayerTreeHostImpl* host_impl = impl().layer_tree_host_impl.get();
+  bool success = host_impl->InitializeRenderer(output_surface.Pass());
+  RendererCapabilities capabilities;
+  if (success) {
+    capabilities =
+        host_impl->GetRendererCapabilities().MainThreadCapabilities();
   }
 
-  impl().layer_tree_host_impl->SetOffscreenContextProvider(
-      offscreen_context_provider);
+  Proxy::MainThreadTaskRunner()->PostTask(
+      FROM_HERE,
+      base::Bind(&ThreadProxy::DidInitializeOutputSurface,
+                 main_thread_weak_ptr_,
+                 success,
+                 capabilities));
 
-  completion->Signal();
+  if (success)
+    impl().scheduler->DidCreateAndInitializeOutputSurface();
 }
 
 void ThreadProxy::FinishGLOnImplThread(CompletionEvent* completion) {
   TRACE_EVENT0("cc", "ThreadProxy::FinishGLOnImplThread");
   DCHECK(IsImplThread());
-  if (impl().layer_tree_host_impl->resource_provider())
-    impl().layer_tree_host_impl->resource_provider()->Finish();
+  if (impl().layer_tree_host_impl->output_surface()) {
+    ContextProvider* context_provider =
+        impl().layer_tree_host_impl->output_surface()->context_provider();
+    if (context_provider)
+      context_provider->ContextGL()->Finish();
+  }
   completion->Signal();
 }
 
 void ThreadProxy::LayerTreeHostClosedOnImplThread(CompletionEvent* completion) {
   TRACE_EVENT0("cc", "ThreadProxy::LayerTreeHostClosedOnImplThread");
   DCHECK(IsImplThread());
+  DCHECK(IsMainThreadBlocked());
   layer_tree_host()->DeleteContentsTexturesOnImplThread(
       impl().layer_tree_host_impl->resource_provider());
-  impl().current_resource_update_controller.reset();
-  impl().layer_tree_host_impl->SetNeedsBeginImplFrame(false);
-  impl().scheduler.reset();
-  impl().layer_tree_host_impl.reset();
+  impl().current_resource_update_controller = nullptr;
+  impl().layer_tree_host_impl->SetNeedsBeginFrames(false);
+  impl().scheduler = nullptr;
+  impl().layer_tree_host_impl = nullptr;
   impl().weak_factory.InvalidateWeakPtrs();
+  // We need to explicitly shutdown the notifier to destroy any weakptrs it is
+  // holding while still on the compositor thread. This also ensures any
+  // callbacks holding a ThreadProxy pointer are cancelled.
+  impl().smoothness_priority_expiration_notifier.Shutdown();
   impl().contents_texture_manager = NULL;
   completion->Signal();
 }
@@ -1506,101 +1236,75 @@ ThreadProxy::BeginMainFrameAndCommitState::BeginMainFrameAndCommitState()
 
 ThreadProxy::BeginMainFrameAndCommitState::~BeginMainFrameAndCommitState() {}
 
-scoped_ptr<base::Value> ThreadProxy::AsValue() const {
-  scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
-
+void ThreadProxy::AsValueInto(base::debug::TracedValue* state) const {
   CompletionEvent completion;
   {
     DebugScopedSetMainThreadBlocked main_thread_blocked(
         const_cast<ThreadProxy*>(this));
+    scoped_refptr<base::debug::TracedValue> state_refptr(state);
     Proxy::ImplThreadTaskRunner()->PostTask(
         FROM_HERE,
         base::Bind(&ThreadProxy::AsValueOnImplThread,
                    impl_thread_weak_ptr_,
                    &completion,
-                   state.get()));
+                   state_refptr));
     completion.Wait();
   }
-  return state.PassAs<base::Value>();
 }
 
 void ThreadProxy::AsValueOnImplThread(CompletionEvent* completion,
-                                      base::DictionaryValue* state) const {
-  state->Set("layer_tree_host_impl",
-             impl().layer_tree_host_impl->AsValue().release());
+                                      base::debug::TracedValue* state) const {
+  state->BeginDictionary("layer_tree_host_impl");
+  impl().layer_tree_host_impl->AsValueInto(state);
+  state->EndDictionary();
   completion->Signal();
 }
 
-bool ThreadProxy::CommitPendingForTesting() {
+bool ThreadProxy::MainFrameWillHappenForTesting() {
   DCHECK(IsMainThread());
-  CommitPendingRequest commit_pending_request;
+  CompletionEvent completion;
+  bool main_frame_will_happen = false;
   {
     DebugScopedSetMainThreadBlocked main_thread_blocked(this);
     Proxy::ImplThreadTaskRunner()->PostTask(
         FROM_HERE,
-        base::Bind(&ThreadProxy::CommitPendingOnImplThreadForTesting,
+        base::Bind(&ThreadProxy::MainFrameWillHappenOnImplThreadForTesting,
                    impl_thread_weak_ptr_,
-                   &commit_pending_request));
-    commit_pending_request.completion.Wait();
+                   &completion,
+                   &main_frame_will_happen));
+    completion.Wait();
   }
-  return commit_pending_request.commit_pending;
+  return main_frame_will_happen;
 }
 
-void ThreadProxy::CommitPendingOnImplThreadForTesting(
-    CommitPendingRequest* request) {
+void ThreadProxy::MainFrameWillHappenOnImplThreadForTesting(
+    CompletionEvent* completion,
+    bool* main_frame_will_happen) {
   DCHECK(IsImplThread());
-  if (impl().layer_tree_host_impl->output_surface())
-    request->commit_pending = impl().scheduler->CommitPending();
-  else
-    request->commit_pending = false;
-  request->completion.Signal();
-}
-
-scoped_ptr<base::Value> ThreadProxy::SchedulerStateAsValueForTesting() {
-  if (IsImplThread())
-    return impl().scheduler->StateAsValue().Pass();
-
-  SchedulerStateRequest scheduler_state_request;
-  {
-    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
-    Proxy::ImplThreadTaskRunner()->PostTask(
-        FROM_HERE,
-        base::Bind(&ThreadProxy::SchedulerStateAsValueOnImplThreadForTesting,
-                   impl_thread_weak_ptr_,
-                   &scheduler_state_request));
-    scheduler_state_request.completion.Wait();
+  if (impl().layer_tree_host_impl->output_surface()) {
+    *main_frame_will_happen = impl().scheduler->MainFrameForTestingWillHappen();
+  } else {
+    *main_frame_will_happen = false;
   }
-  return scheduler_state_request.state.Pass();
-}
-
-void ThreadProxy::SchedulerStateAsValueOnImplThreadForTesting(
-    SchedulerStateRequest* request) {
-  DCHECK(IsImplThread());
-  request->state = impl().scheduler->StateAsValue();
-  request->completion.Signal();
+  completion->Signal();
 }
 
 void ThreadProxy::RenewTreePriority() {
   DCHECK(IsImplThread());
   bool smoothness_takes_priority =
       impl().layer_tree_host_impl->pinch_gesture_active() ||
-      impl().layer_tree_host_impl->IsCurrentlyScrolling() ||
-      impl().layer_tree_host_impl->page_scale_animation_active();
+      impl().layer_tree_host_impl->page_scale_animation_active() ||
+      impl().layer_tree_host_impl->IsActivelyScrolling();
 
-  base::TimeTicks now = impl().layer_tree_host_impl->CurrentPhysicalTimeTicks();
-
-  // Update expiration time if smoothness currently takes priority.
-  if (smoothness_takes_priority) {
-    impl().smoothness_takes_priority_expiration_time =
-        now + base::TimeDelta::FromMilliseconds(
-                  kSmoothnessTakesPriorityExpirationDelay * 1000);
-  }
+  // Schedule expiration if smoothness currently takes priority.
+  if (smoothness_takes_priority)
+    impl().smoothness_priority_expiration_notifier.Schedule();
 
   // We use the same priority for both trees by default.
   TreePriority priority = SAME_PRIORITY_FOR_BOTH_TREES;
 
-  // Smoothness takes priority if expiration time is in the future.
-  if (impl().smoothness_takes_priority_expiration_time > now)
+  // Smoothness takes priority if we have an expiration for it scheduled.
+  if (impl().smoothness_priority_expiration_notifier.HasPendingNotification())
     priority = SMOOTHNESS_TAKES_PRIORITY;
 
   // New content always takes priority when the active tree has
@@ -1608,12 +1312,23 @@ void ThreadProxy::RenewTreePriority() {
   if (impl().layer_tree_host_impl->active_tree()->ContentsTexturesPurged() ||
       impl().layer_tree_host_impl->active_tree()->ViewportSizeInvalid() ||
       impl().layer_tree_host_impl->EvictedUIResourcesExist() ||
-      impl().input_throttled_until_commit)
+      impl().input_throttled_until_commit) {
+    // Once we enter NEW_CONTENTS_TAKES_PRIORITY mode, visible tiles on active
+    // tree might be freed. We need to set RequiresHighResToDraw to ensure that
+    // high res tiles will be required to activate pending tree.
+    impl().layer_tree_host_impl->SetRequiresHighResToDraw();
     priority = NEW_CONTENT_TAKES_PRIORITY;
+  }
 
   impl().layer_tree_host_impl->SetTreePriority(priority);
-  impl().scheduler->SetSmoothnessTakesPriority(priority ==
-                                               SMOOTHNESS_TAKES_PRIORITY);
+
+  // Only put the scheduler in impl latency prioritization mode if we don't
+  // have a scroll listener. This gives the scroll listener a better chance of
+  // handling scroll updates within the same frame. The tree itself is still
+  // kept in prefer smoothness mode to allow checkerboarding.
+  impl().scheduler->SetImplLatencyTakesPriority(
+      priority == SMOOTHNESS_TAKES_PRIORITY &&
+      !impl().layer_tree_host_impl->scroll_affects_scroll_handler());
 
   // Notify the the client of this compositor via the output surface.
   // TODO(epenner): Route this to compositor-thread instead of output-surface
@@ -1623,51 +1338,19 @@ void ThreadProxy::RenewTreePriority() {
         .layer_tree_host_impl->output_surface()
         ->UpdateSmoothnessTakesPriority(priority == SMOOTHNESS_TAKES_PRIORITY);
   }
-
-  base::TimeDelta delay =
-      impl().smoothness_takes_priority_expiration_time - now;
-
-  // Need to make sure a delayed task is posted when we have smoothness
-  // takes priority expiration time in the future.
-  if (delay <= base::TimeDelta())
-    return;
-  if (impl().renew_tree_priority_pending)
-    return;
-
-  Proxy::ImplThreadTaskRunner()->PostDelayedTask(
-      FROM_HERE,
-      base::Bind(&ThreadProxy::RenewTreePriorityOnImplThread,
-                 impl_thread_weak_ptr_),
-      delay);
-
-  impl().renew_tree_priority_pending = true;
-}
-
-void ThreadProxy::RenewTreePriorityOnImplThread() {
-  DCHECK(impl().renew_tree_priority_pending);
-  impl().renew_tree_priority_pending = false;
-
-  RenewTreePriority();
-}
-
-void ThreadProxy::RequestScrollbarAnimationOnImplThread(base::TimeDelta delay) {
-  Proxy::ImplThreadTaskRunner()->PostDelayedTask(
-      FROM_HERE,
-      base::Bind(&ThreadProxy::StartScrollbarAnimationOnImplThread,
-                 impl_thread_weak_ptr_),
-      delay);
 }
 
-void ThreadProxy::StartScrollbarAnimationOnImplThread() {
-  impl().layer_tree_host_impl->StartScrollbarAnimation();
+void ThreadProxy::PostDelayedScrollbarFadeOnImplThread(
+    const base::Closure& start_fade,
+    base::TimeDelta delay) {
+  Proxy::ImplThreadTaskRunner()->PostDelayedTask(FROM_HERE, start_fade, delay);
 }
 
-void ThreadProxy::DidActivatePendingTree() {
+void ThreadProxy::DidActivateSyncTree() {
+  TRACE_EVENT0("cc", "ThreadProxy::DidActivateSyncTreeOnImplThread");
   DCHECK(IsImplThread());
-  TRACE_EVENT0("cc", "ThreadProxy::DidActivatePendingTreeOnImplThread");
 
-  if (impl().completion_event_for_commit_held_on_tree_activation &&
-      !impl().layer_tree_host_impl->pending_tree()) {
+  if (impl().completion_event_for_commit_held_on_tree_activation) {
     TRACE_EVENT_INSTANT0(
         "cc", "ReleaseCommitbyActivation", TRACE_EVENT_SCOPE_THREAD);
     DCHECK(impl().layer_tree_host_impl->settings().impl_side_painting);
@@ -1677,8 +1360,7 @@ void ThreadProxy::DidActivatePendingTree() {
 
   UpdateBackgroundAnimateTicking();
 
-  impl().commit_to_activate_duration_history.InsertSample(
-      base::TimeTicks::HighResNow() - impl().commit_complete_time);
+  impl().timing_history.DidActivateSyncTree();
 }
 
 void ThreadProxy::DidManageTiles() {