Chromium Code Reviews| Index: cc/trees/single_thread_proxy.cc |
| diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc |
| index c254311a9300edb65bc8d9006bb6e5c613c6f6f1..254bdf174ced5eaeabce23bcf68481b6b6142a55 100644 |
| --- a/cc/trees/single_thread_proxy.cc |
| +++ b/cc/trees/single_thread_proxy.cc |
| @@ -33,7 +33,11 @@ SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host, |
| layer_tree_host_(layer_tree_host), |
| client_(client), |
| next_frame_is_newly_committed_frame_(false), |
| - inside_draw_(false) { |
| + inside_draw_(false), |
| + defer_commits_(false), |
| + commit_was_deferred_(false), |
| + commit_requested_(false), |
| + weak_factory_(this) { |
| TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy"); |
| DCHECK(Proxy::IsMainThread()); |
| DCHECK(layer_tree_host); |
| @@ -73,13 +77,26 @@ void SingleThreadProxy::SetLayerTreeHostClientReady() { |
| TRACE_EVENT0("cc", "SingleThreadProxy::SetLayerTreeHostClientReady"); |
| // Scheduling is controlled by the embedder in the single thread case, so |
| // nothing to do. |
| + DCHECK(Proxy::IsMainThread()); |
| + DebugScopedSetImplThread impl(this); |
| + if (layer_tree_host_->settings().single_thread_proxy_scheduler && |
| + !scheduler_on_impl_thread_) { |
| + SchedulerSettings scheduler_settings(layer_tree_host_->settings()); |
| + scheduler_on_impl_thread_ = Scheduler::Create(this, |
| + scheduler_settings, |
| + layer_tree_host_->id(), |
| + MainThreadTaskRunner()); |
| + scheduler_on_impl_thread_->SetCanStart(); |
| + scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible()); |
| + } |
| } |
| void SingleThreadProxy::SetVisible(bool visible) { |
| TRACE_EVENT0("cc", "SingleThreadProxy::SetVisible"); |
| DebugScopedSetImplThread impl(this); |
| layer_tree_host_impl_->SetVisible(visible); |
| - |
| + if (scheduler_on_impl_thread_) |
| + scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible()); |
| // Changing visibility could change ShouldComposite(). |
| UpdateBackgroundAnimateTicking(); |
| } |
| @@ -106,9 +123,14 @@ void SingleThreadProxy::CreateAndInitializeOutputSurface() { |
| layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(success); |
| - if (!success) { |
| - // Force another recreation attempt to happen by requesting another commit. |
| - SetNeedsCommit(); |
| + if (success) { |
| + if (scheduler_on_impl_thread_) |
| + scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface(); |
| + } else if (Proxy::MainThreadTaskRunner()) { |
| + Proxy::MainThreadTaskRunner()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&SingleThreadProxy::CreateAndInitializeOutputSurface, |
| + weak_factory_.GetWeakPtr())); |
| } |
| } |
| @@ -122,17 +144,39 @@ void SingleThreadProxy::SetNeedsAnimate() { |
| TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate"); |
| DCHECK(Proxy::IsMainThread()); |
| client_->ScheduleAnimation(); |
| + SetNeedsCommit(); |
| } |
| void SingleThreadProxy::SetNeedsUpdateLayers() { |
| TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers"); |
| DCHECK(Proxy::IsMainThread()); |
| - client_->ScheduleComposite(); |
| + SetNeedsCommit(); |
| } |
| -void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) { |
| +void SingleThreadProxy::DoCommit(base::TimeTicks frame_begin_time) { |
| TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit"); |
| DCHECK(Proxy::IsMainThread()); |
| + layer_tree_host_->WillBeginMainFrame(); |
| + layer_tree_host_->Layout(); |
| + layer_tree_host_->AnimateLayers(frame_begin_time); |
| + commit_requested_ = false; |
| + |
| + if (PrioritizedResourceManager* contents_texture_manager = |
| + layer_tree_host_->contents_texture_manager()) { |
| + contents_texture_manager->UnlinkAndClearEvictedBackings(); |
| + contents_texture_manager->SetMaxMemoryLimitBytes( |
| + layer_tree_host_impl_->memory_allocation_limit_bytes()); |
| + contents_texture_manager->SetExternalPriorityCutoff( |
| + layer_tree_host_impl_->memory_allocation_priority_cutoff()); |
| + } |
| + |
| + scoped_ptr<ResourceUpdateQueue> queue = |
| + make_scoped_ptr(new ResourceUpdateQueue); |
| + |
| + layer_tree_host_->UpdateLayers(queue.get()); |
| + |
| + layer_tree_host_->WillCommit(); |
| + |
| // Commit immediately. |
| { |
| DebugScopedSetMainThreadBlocked main_thread_blocked(this); |
| @@ -166,6 +210,8 @@ void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) { |
| layer_tree_host_impl_->CommitComplete(); |
| + UpdateBackgroundAnimateTicking(); |
| + |
| #if DCHECK_IS_ON |
| // In the single-threaded case, the scale and scroll deltas should never be |
| // touched on the impl layer tree. |
| @@ -182,32 +228,64 @@ void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) { |
| stats_instrumentation->AccumulateAndClearMainThreadStats(); |
| } |
| layer_tree_host_->CommitComplete(); |
| + layer_tree_host_->DidBeginMainFrame(); |
| + timing_history_.DidCommit(); |
| + |
| next_frame_is_newly_committed_frame_ = true; |
| } |
| void SingleThreadProxy::SetNeedsCommit() { |
| DCHECK(Proxy::IsMainThread()); |
| + DebugScopedSetImplThread impl(this); |
| client_->ScheduleComposite(); |
| + if (scheduler_on_impl_thread_) |
| + scheduler_on_impl_thread_->SetNeedsCommit(); |
| + commit_requested_ = true; |
| } |
| void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) { |
| TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw"); |
| - SetNeedsRedrawRectOnImplThread(damage_rect); |
| + DCHECK(Proxy::IsMainThread()); |
| + DebugScopedSetImplThread impl(this); |
| client_->ScheduleComposite(); |
| + SetNeedsRedrawRectOnImplThread(damage_rect); |
| } |
| void SingleThreadProxy::SetNextCommitWaitsForActivation() { |
| // There is no activation here other than commit. So do nothing. |
| + DCHECK(Proxy::IsMainThread()); |
| } |
| void SingleThreadProxy::SetDeferCommits(bool defer_commits) { |
| - // Thread-only feature. |
| - NOTREACHED(); |
| + DCHECK(Proxy::IsMainThread()); |
| + // Deferring commits only makes sense if there's a scheduler. |
| + if (!scheduler_on_impl_thread_) |
|
enne (OOO)
2014/06/27 19:16:51
This has to not be a DCHECK anymore because the sc
|
| + return; |
| + if (defer_commits_ == defer_commits) |
| + return; |
| + |
| + if (defer_commits) |
| + TRACE_EVENT_ASYNC_BEGIN0("cc", "SingleThreadProxy::SetDeferCommits", this); |
| + else |
| + TRACE_EVENT_ASYNC_END0("cc", "SingleThreadProxy::SetDeferCommits", this); |
| + |
| + defer_commits_ = defer_commits; |
| + if (!defer_commits_ && commit_was_deferred_) { |
| + scheduler_on_impl_thread_->NotifyBeginMainFrameStarted(); |
| + scheduler_on_impl_thread_->NotifyReadyToCommit(); |
| + commit_was_deferred_ = false; |
| + } |
| } |
| -bool SingleThreadProxy::CommitRequested() const { return false; } |
| +bool SingleThreadProxy::CommitRequested() const { |
| + DCHECK(Proxy::IsMainThread()); |
| + return commit_requested_; |
| +} |
| -bool SingleThreadProxy::BeginMainFrameRequested() const { return false; } |
| +bool SingleThreadProxy::BeginMainFrameRequested() const { |
| + DCHECK(Proxy::IsMainThread()); |
| + return commit_requested_; |
| +} |
| size_t SingleThreadProxy::MaxPartialTextureUpdates() const { |
| return std::numeric_limits<size_t>::max(); |
| @@ -223,6 +301,7 @@ void SingleThreadProxy::Stop() { |
| BlockingTaskRunner::CapturePostTasks blocked; |
| layer_tree_host_->DeleteContentsTexturesOnImplThread( |
| layer_tree_host_impl_->resource_provider()); |
| + scheduler_on_impl_thread_.reset(); |
| layer_tree_host_impl_.reset(); |
| } |
| layer_tree_host_ = NULL; |
| @@ -233,15 +312,19 @@ void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) { |
| "cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw); |
| DCHECK(Proxy::IsImplThread()); |
| UpdateBackgroundAnimateTicking(); |
| + if (scheduler_on_impl_thread_) |
| + scheduler_on_impl_thread_->SetCanDraw(can_draw); |
| } |
| void SingleThreadProxy::NotifyReadyToActivate() { |
| - // Thread-only feature. |
| + // Impl-side painting only. |
| NOTREACHED(); |
| } |
| void SingleThreadProxy::SetNeedsRedrawOnImplThread() { |
| client_->ScheduleComposite(); |
| + if (scheduler_on_impl_thread_) |
| + scheduler_on_impl_thread_->SetNeedsRedraw(); |
| } |
| void SingleThreadProxy::SetNeedsAnimateOnImplThread() { |
| @@ -249,17 +332,14 @@ void SingleThreadProxy::SetNeedsAnimateOnImplThread() { |
| } |
| void SingleThreadProxy::SetNeedsManageTilesOnImplThread() { |
| - // Thread-only/Impl-side-painting-only feature. |
| + // Impl-side painting only. |
| NOTREACHED(); |
| } |
| void SingleThreadProxy::SetNeedsRedrawRectOnImplThread( |
| const gfx::Rect& damage_rect) { |
| - // TODO(brianderson): Once we move render_widget scheduling into this class, |
| - // we can treat redraw requests more efficiently than CommitAndRedraw |
| - // requests. |
| layer_tree_host_impl_->SetViewportDamage(damage_rect); |
| - SetNeedsCommit(); |
| + SetNeedsRedrawOnImplThread(); |
| } |
| void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() { |
| @@ -269,6 +349,8 @@ void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() { |
| void SingleThreadProxy::SetNeedsCommitOnImplThread() { |
| client_->ScheduleComposite(); |
| + if (scheduler_on_impl_thread_) |
| + scheduler_on_impl_thread_->SetNeedsCommit(); |
| } |
| void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread( |
| @@ -305,66 +387,58 @@ void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() { |
| layer_tree_host_impl_->GetRendererCapabilities().MainThreadCapabilities(); |
| } |
| +void SingleThreadProxy::DidActivatePendingTree() { |
| + // Impl-side painting only. |
| + NOTREACHED(); |
| +} |
| + |
| +void SingleThreadProxy::DidManageTiles() { |
| + // Impl-side painting only. |
| + NOTREACHED(); |
| +} |
| + |
| void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() { |
| TRACE_EVENT0("cc", "SingleThreadProxy::DidLoseOutputSurfaceOnImplThread"); |
| - // Cause a commit so we can notice the lost context. |
| - SetNeedsCommitOnImplThread(); |
| + { |
| + DebugScopedSetMainThread main(this); |
| + // This must happen before we notify the scheduler as it may try to recreate |
| + // the output surface if already in BEGIN_IMPL_FRAME_STATE_IDLE. |
| + layer_tree_host_->DidLoseOutputSurface(); |
| + } |
| client_->DidAbortSwapBuffers(); |
| + if (scheduler_on_impl_thread_) |
| + scheduler_on_impl_thread_->DidLoseOutputSurface(); |
| } |
| void SingleThreadProxy::DidSwapBuffersOnImplThread() { |
| + TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersOnImplThread"); |
| + if (scheduler_on_impl_thread_) |
| + scheduler_on_impl_thread_->DidSwapBuffers(); |
| client_->DidPostSwapBuffers(); |
| } |
| void SingleThreadProxy::DidSwapBuffersCompleteOnImplThread() { |
| TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersCompleteOnImplThread"); |
| - client_->DidCompleteSwapBuffers(); |
| + if (scheduler_on_impl_thread_) |
| + scheduler_on_impl_thread_->DidSwapBuffersComplete(); |
| + layer_tree_host_->DidCompleteSwapBuffers(); |
| +} |
| + |
| +void SingleThreadProxy::BeginFrame(const BeginFrameArgs& args) { |
| + TRACE_EVENT0("cc", "SingleThreadProxy::BeginFrame"); |
| + if (scheduler_on_impl_thread_) |
| + scheduler_on_impl_thread_->BeginImplFrame(args); |
| } |
| -// Called by the legacy scheduling path (e.g. where render_widget does the |
| -// scheduling) |
| void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) { |
| TRACE_EVENT0("cc", "SingleThreadProxy::CompositeImmediately"); |
| DCHECK(Proxy::IsMainThread()); |
| DCHECK(!layer_tree_host_->output_surface_lost()); |
| - layer_tree_host_->AnimateLayers(frame_begin_time); |
| - |
| - if (PrioritizedResourceManager* contents_texture_manager = |
| - layer_tree_host_->contents_texture_manager()) { |
| - contents_texture_manager->UnlinkAndClearEvictedBackings(); |
| - contents_texture_manager->SetMaxMemoryLimitBytes( |
| - layer_tree_host_impl_->memory_allocation_limit_bytes()); |
| - contents_texture_manager->SetExternalPriorityCutoff( |
| - layer_tree_host_impl_->memory_allocation_priority_cutoff()); |
| - } |
| - |
| - scoped_ptr<ResourceUpdateQueue> queue = |
| - make_scoped_ptr(new ResourceUpdateQueue); |
| - layer_tree_host_->UpdateLayers(queue.get()); |
| - layer_tree_host_->WillCommit(); |
| - DoCommit(queue.Pass()); |
| - layer_tree_host_->DidBeginMainFrame(); |
| + DoCommit(frame_begin_time); |
| LayerTreeHostImpl::FrameData frame; |
| - if (DoComposite(frame_begin_time, &frame)) { |
| - { |
| - DebugScopedSetMainThreadBlocked main_thread_blocked(this); |
| - DebugScopedSetImplThread impl(this); |
| - |
| - // This CapturePostTasks should be destroyed before |
| - // DidCommitAndDrawFrame() is called since that goes out to the embedder, |
| - // and we want the embedder to receive its callbacks before that. |
| - // NOTE: This maintains consistent ordering with the ThreadProxy since |
| - // the DidCommitAndDrawFrame() must be post-tasked from the impl thread |
| - // there as the main thread is not blocked, so any posted tasks inside |
| - // the swap buffers will execute first. |
| - BlockingTaskRunner::CapturePostTasks blocked; |
| - |
| - layer_tree_host_impl_->SwapBuffers(frame); |
| - } |
| - DidSwapFrame(); |
| - } |
| + DoComposite(frame_begin_time, &frame); |
| } |
| scoped_ptr<base::Value> SingleThreadProxy::AsValue() const { |
| @@ -403,13 +477,11 @@ void SingleThreadProxy::UpdateBackgroundAnimateTicking() { |
| !ShouldComposite() && layer_tree_host_impl_->active_tree()->root_layer()); |
| } |
| -bool SingleThreadProxy::DoComposite( |
| - base::TimeTicks frame_begin_time, |
| - LayerTreeHostImpl::FrameData* frame) { |
| +DrawResult SingleThreadProxy::DoComposite(base::TimeTicks frame_begin_time, |
| + LayerTreeHostImpl::FrameData* frame) { |
| TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite"); |
| DCHECK(!layer_tree_host_->output_surface_lost()); |
| - bool lost_output_surface = false; |
| { |
| DebugScopedSetImplThread impl(this); |
| base::AutoReset<bool> mark_inside(&inside_draw_, true); |
| @@ -420,9 +492,11 @@ bool SingleThreadProxy::DoComposite( |
| // CanDraw() as well. |
| if (!ShouldComposite()) { |
| UpdateBackgroundAnimateTicking(); |
| - return false; |
| + return DRAW_ABORTED_CANT_DRAW; |
| } |
| + timing_history_.DidStartDrawing(); |
| + |
| layer_tree_host_impl_->Animate( |
| layer_tree_host_impl_->CurrentFrameTimeTicks()); |
| UpdateBackgroundAnimateTicking(); |
| @@ -432,24 +506,42 @@ bool SingleThreadProxy::DoComposite( |
| layer_tree_host_impl_->DrawLayers(frame, frame_begin_time); |
| layer_tree_host_impl_->DidDrawAllLayers(*frame); |
| } |
| - lost_output_surface = layer_tree_host_impl_->IsContextLost(); |
| bool start_ready_animations = true; |
| layer_tree_host_impl_->UpdateAnimationState(start_ready_animations); |
| layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame(); |
| + |
| + timing_history_.DidFinishDrawing(); |
| } |
| - if (lost_output_surface) { |
| - layer_tree_host_->DidLoseOutputSurface(); |
| - return false; |
| + { |
| + DebugScopedSetImplThread impl(this); |
| + |
| + if (layer_tree_host_impl_->IsContextLost()) { |
| + DidLoseOutputSurfaceOnImplThread(); |
| + } else { |
| + // This CapturePostTasks should be destroyed before |
| + // DidCommitAndDrawFrame() is called since that goes out to the embedder, |
| + // and we want the embedder to receive its callbacks before that. |
| + // NOTE: This maintains consistent ordering with the ThreadProxy since |
| + // the DidCommitAndDrawFrame() must be post-tasked from the impl thread |
| + // there as the main thread is not blocked, so any posted tasks inside |
| + // the swap buffers will execute first. |
| + DebugScopedSetMainThreadBlocked main_thread_blocked(this); |
| + |
| + BlockingTaskRunner::CapturePostTasks blocked; |
| + layer_tree_host_impl_->SwapBuffers(*frame); |
| + } |
| } |
| + DidCommitAndDrawFrame(); |
| - return true; |
| + return DRAW_SUCCESS; |
| } |
| -void SingleThreadProxy::DidSwapFrame() { |
| +void SingleThreadProxy::DidCommitAndDrawFrame() { |
| if (next_frame_is_newly_committed_frame_) { |
| + DebugScopedSetMainThread main(this); |
| next_frame_is_newly_committed_frame_ = false; |
| layer_tree_host_->DidCommitAndDrawFrame(); |
| } |
| @@ -457,4 +549,112 @@ void SingleThreadProxy::DidSwapFrame() { |
| bool SingleThreadProxy::CommitPendingForTesting() { return false; } |
| +scoped_ptr<base::Value> SingleThreadProxy::SchedulerAsValueForTesting() { |
| + DebugScopedSetImplThread impl(this); |
| + if (!scheduler_on_impl_thread_) |
| + return make_scoped_ptr(base::Value::CreateNullValue()).Pass(); |
| + return scheduler_on_impl_thread_->AsValue().Pass(); |
| +} |
| + |
| +void SingleThreadProxy::SetNeedsBeginFrame(bool enable) { |
| + layer_tree_host_impl_->SetNeedsBeginFrame(enable); |
| +} |
| + |
| +void SingleThreadProxy::WillBeginImplFrame(const BeginFrameArgs& args) { |
| + layer_tree_host_impl_->WillBeginImplFrame(args); |
| +} |
| + |
| +void SingleThreadProxy::ScheduledActionSendBeginMainFrame() { |
| + TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionSendBeginMainFrame"); |
| + if (defer_commits_) { |
| + DCHECK(!commit_was_deferred_); |
| + commit_was_deferred_ = true; |
| + layer_tree_host_->DidDeferCommit(); |
| + return; |
| + } |
| + timing_history_.DidBeginMainFrame(); |
| + |
| + DCHECK(scheduler_on_impl_thread_); |
| + scheduler_on_impl_thread_->NotifyBeginMainFrameStarted(); |
| + scheduler_on_impl_thread_->NotifyReadyToCommit(); |
| +} |
| + |
| +DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapIfPossible() { |
| + DebugScopedSetImplThread impl(this); |
| + if (layer_tree_host_impl_->IsContextLost()) { |
| + DidCommitAndDrawFrame(); |
| + return DRAW_SUCCESS; |
| + } |
| + |
| + LayerTreeHostImpl::FrameData frame; |
| + return DoComposite(layer_tree_host_impl_->CurrentFrameTimeTicks(), &frame); |
| +} |
| + |
| +DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapForced() { |
| + NOTREACHED(); |
| + return INVALID_RESULT; |
| +} |
| + |
| +void SingleThreadProxy::ScheduledActionCommit() { |
| + DebugScopedSetMainThread main(this); |
| + DoCommit(layer_tree_host_impl_->CurrentFrameTimeTicks()); |
| +} |
| + |
| +void SingleThreadProxy::ScheduledActionAnimate() { |
| + TRACE_EVENT0("cc", "ScheduledActionAnimate"); |
| + layer_tree_host_impl_->Animate( |
| + layer_tree_host_impl_->CurrentFrameTimeTicks()); |
| +} |
| + |
| +void SingleThreadProxy::ScheduledActionUpdateVisibleTiles() { |
| + // Impl-side painting only. |
| + NOTREACHED(); |
| +} |
| + |
| +void SingleThreadProxy::ScheduledActionActivatePendingTree() { |
| + // Impl-side painting only. |
| + NOTREACHED(); |
| +} |
| + |
| +void SingleThreadProxy::ScheduledActionBeginOutputSurfaceCreation() { |
| + DebugScopedSetMainThread main(this); |
| + DCHECK(scheduler_on_impl_thread_); |
| + // If possible, create the output surface in a post task. Synchronously |
| + // creating the output surface makes tests more awkward since this differs |
| + // from the ThreadProxy behavior. However, sometimes there is no |
| + // task runner. |
| + if (Proxy::MainThreadTaskRunner()) { |
| + Proxy::MainThreadTaskRunner()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&SingleThreadProxy::CreateAndInitializeOutputSurface, |
| + weak_factory_.GetWeakPtr())); |
| + } else { |
| + CreateAndInitializeOutputSurface(); |
| + } |
| +} |
| + |
| +void SingleThreadProxy::ScheduledActionManageTiles() { |
| + // Impl-side painting only. |
| + NOTREACHED(); |
| +} |
| + |
| +void SingleThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) { |
| +} |
| + |
| +base::TimeDelta SingleThreadProxy::DrawDurationEstimate() { |
| + return timing_history_.DrawDurationEstimate(); |
| +} |
| + |
| +base::TimeDelta SingleThreadProxy::BeginMainFrameToCommitDurationEstimate() { |
| + return timing_history_.BeginMainFrameToCommitDurationEstimate(); |
| +} |
| + |
| +base::TimeDelta SingleThreadProxy::CommitToActivateDurationEstimate() { |
| + return timing_history_.CommitToActivateDurationEstimate(); |
| +} |
| + |
| +void SingleThreadProxy::DidBeginImplFrameDeadline() { |
| + layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame(); |
| +} |
| + |
| } // namespace cc |