Index: cc/trees/single_thread_proxy.cc |
diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc |
index dcd4cf679b74500ee3ad7fa901d675f6700de710..b33a29d048e18812118a29b689a4cfa3e90eb91d 100644 |
--- a/cc/trees/single_thread_proxy.cc |
+++ b/cc/trees/single_thread_proxy.cc |
@@ -33,8 +33,11 @@ SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host, |
layer_tree_host_(layer_tree_host), |
client_(client), |
created_offscreen_context_provider_(false), |
+ weak_factory_(this), |
next_frame_is_newly_committed_frame_(false), |
- inside_draw_(false) { |
+ inside_draw_(false), |
+ defer_commits_(false), |
+ finish_commit_deferred_(false) { |
TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy"); |
DCHECK(Proxy::IsMainThread()); |
DCHECK(layer_tree_host); |
@@ -47,6 +50,10 @@ SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host, |
void SingleThreadProxy::Start() { |
DebugScopedSetImplThread impl(this); |
layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this); |
+ SchedulerSettings scheduler_settings(layer_tree_host_->settings()); |
+ scheduler_on_impl_thread_ = |
+ Scheduler::Create(this, scheduler_settings, layer_tree_host_->id()); |
+ scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible()); |
} |
SingleThreadProxy::~SingleThreadProxy() { |
@@ -60,14 +67,15 @@ bool SingleThreadProxy::CompositeAndReadback(void* pixels, |
const gfx::Rect& rect) { |
TRACE_EVENT0("cc", "SingleThreadProxy::CompositeAndReadback"); |
DCHECK(Proxy::IsMainThread()); |
- |
- gfx::Rect device_viewport_damage_rect = rect; |
- |
- LayerTreeHostImpl::FrameData frame; |
- if (!CommitAndComposite(gfx::FrameTime::Now(), |
- device_viewport_damage_rect, |
- true, // for_readback |
- &frame)) |
+ // TODO(enne): make this go through the SetNeedsForcedCommitForReadback logic. |
+ bool do_commit = true; |
+ bool for_readback = true; |
+ gfx::Rect device_viewport_damage_rect(rect); |
+ if (CommitAndCompositeInternal(gfx::FrameTime::Now(), |
+ device_viewport_damage_rect, |
+ do_commit, |
+ for_readback).draw_result != |
+ DrawSwapReadbackResult::DRAW_SUCCESS) |
return false; |
{ |
@@ -99,12 +107,16 @@ 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); |
+ scheduler_on_impl_thread_->SetCanStart(); |
} |
void SingleThreadProxy::SetVisible(bool visible) { |
TRACE_EVENT0("cc", "SingleThreadProxy::SetVisible"); |
DebugScopedSetImplThread impl(this); |
layer_tree_host_impl_->SetVisible(visible); |
+ scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible()); |
// Changing visibility could change ShouldComposite(). |
UpdateBackgroundAnimateTicking(); |
@@ -161,14 +173,25 @@ void SingleThreadProxy::CreateAndInitializeOutputSurface() { |
} |
OnOutputSurfaceInitializeAttempted(initialized); |
+ |
+ // This must happen after OnCreateAndInitializeOutputSurfaceAttempted as it |
+ // causes a commit and the output surface needs to be initialized beforehand. |
+ if (initialized) { |
+ DebugScopedSetImplThread impl(this); |
+ scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface(); |
+ } |
} |
void SingleThreadProxy::OnOutputSurfaceInitializeAttempted(bool success) { |
LayerTreeHost::CreateResult result = |
layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(success); |
if (result == LayerTreeHost::CreateFailedButTryAgain) { |
- // Force another recreation attempt to happen by requesting another commit. |
- SetNeedsCommit(); |
+ if (!weak_ptr_) |
+ weak_ptr_ = weak_factory_.GetWeakPtr(); |
danakj
2014/02/20 20:56:40
I don't think you need a member variable for this.
enne (OOO)
2014/02/20 21:07:13
It seemed silly to create a new weak pointer every
danakj
2014/02/20 21:09:47
This is called rarely, and I think it's not a typi
enne (OOO)
2014/02/21 19:34:09
Removed weak pointer.
|
+ Proxy::MainThreadTaskRunner()->PostTask( |
+ FROM_HERE, |
+ base::Bind(&SingleThreadProxy::CreateAndInitializeOutputSurface, |
+ weak_ptr_)); |
} |
} |
@@ -181,18 +204,38 @@ const RendererCapabilities& SingleThreadProxy::GetRendererCapabilities() const { |
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); |
+ |
+ 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); |
@@ -226,6 +269,8 @@ void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) { |
layer_tree_host_impl_->CommitComplete(); |
+ UpdateBackgroundAnimateTicking(); |
+ |
#ifndef NDEBUG |
// In the single-threaded case, the scale and scroll deltas should never be |
// touched on the impl layer tree. |
@@ -242,32 +287,49 @@ 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()); |
- client_->ScheduleComposite(); |
+ scheduler_on_impl_thread_->SetNeedsCommit(); |
} |
void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) { |
TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw"); |
+ DCHECK(Proxy::IsMainThread()); |
+ DebugScopedSetImplThread impl(this); |
SetNeedsRedrawRectOnImplThread(damage_rect); |
- client_->ScheduleComposite(); |
} |
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()); |
+ if (defer_commits_ == defer_commits) |
+ return; |
+ |
+ defer_commits_ = defer_commits; |
+ if (!defer_commits_ && finish_commit_deferred_) { |
+ scheduler_on_impl_thread_->FinishCommit(); |
+ finish_commit_deferred_ = false; |
+ } |
} |
-bool SingleThreadProxy::CommitRequested() const { return false; } |
+bool SingleThreadProxy::CommitRequested() const { |
+ DCHECK(Proxy::IsMainThread()); |
+ return finish_commit_deferred_; |
+} |
-bool SingleThreadProxy::BeginMainFrameRequested() const { return false; } |
+bool SingleThreadProxy::BeginMainFrameRequested() const { |
+ DCHECK(Proxy::IsMainThread()); |
+ return finish_commit_deferred_; |
+} |
size_t SingleThreadProxy::MaxPartialTextureUpdates() const { |
return std::numeric_limits<size_t>::max(); |
@@ -282,6 +344,7 @@ void SingleThreadProxy::Stop() { |
layer_tree_host_->DeleteContentsTexturesOnImplThread( |
layer_tree_host_impl_->resource_provider()); |
+ scheduler_on_impl_thread_.reset(); |
layer_tree_host_impl_.reset(); |
} |
layer_tree_host_ = NULL; |
@@ -292,29 +355,27 @@ void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) { |
"cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw); |
DCHECK(Proxy::IsImplThread()); |
UpdateBackgroundAnimateTicking(); |
+ scheduler_on_impl_thread_->SetCanDraw(can_draw); |
} |
void SingleThreadProxy::NotifyReadyToActivate() { |
- // Thread-only feature. |
+ // Impl-side painting only. |
NOTREACHED(); |
} |
void SingleThreadProxy::SetNeedsRedrawOnImplThread() { |
- client_->ScheduleComposite(); |
+ scheduler_on_impl_thread_->SetNeedsRedraw(); |
} |
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() { |
@@ -323,7 +384,7 @@ void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() { |
} |
void SingleThreadProxy::SetNeedsCommitOnImplThread() { |
- client_->ScheduleComposite(); |
+ scheduler_on_impl_thread_->SetNeedsCommit(); |
} |
void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread( |
@@ -370,14 +431,34 @@ void SingleThreadProxy::SendManagedMemoryStats() { |
bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; } |
+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(); |
+ } |
+ |
+ // TODO(enne): this client call could maybe be removed. |
client_->DidAbortSwapBuffers(); |
+ |
+ scheduler_on_impl_thread_->DidLoseOutputSurface(); |
} |
void SingleThreadProxy::DidSwapBuffersOnImplThread() { |
+ // TODO(enne): Maybe this is redundant with DidCommitAndDrawFrame and can be |
+ // removed? |
client_->DidPostSwapBuffers(); |
} |
@@ -386,34 +467,20 @@ void SingleThreadProxy::OnSwapBuffersCompleteOnImplThread() { |
client_->DidCompleteSwapBuffers(); |
} |
-// Called by the legacy scheduling path (e.g. where render_widget does the |
-// scheduling) |
+void SingleThreadProxy::BeginImplFrame(const BeginFrameArgs& args) { |
+ TRACE_EVENT0("cc", "ThreadProxy::BeginImplFrame"); |
+ scheduler_on_impl_thread_->BeginImplFrame(args); |
+} |
+ |
void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) { |
TRACE_EVENT0("cc", "SingleThreadProxy::CompositeImmediately"); |
+ bool do_commit = true; |
+ bool for_readback = false; |
gfx::Rect device_viewport_damage_rect; |
- |
- LayerTreeHostImpl::FrameData frame; |
- if (CommitAndComposite(frame_begin_time, |
- device_viewport_damage_rect, |
- false, // for_readback |
- &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(); |
- } |
+ CommitAndCompositeInternal(gfx::FrameTime::Now(), |
+ device_viewport_damage_rect, |
+ do_commit, |
+ for_readback); |
} |
scoped_ptr<base::Value> SingleThreadProxy::AsValue() const { |
@@ -440,34 +507,18 @@ void SingleThreadProxy::ForceSerializeOnSwapBuffers() { |
} |
} |
-bool SingleThreadProxy::CommitAndComposite( |
- base::TimeTicks frame_begin_time, |
- const gfx::Rect& device_viewport_damage_rect, |
- bool for_readback, |
- LayerTreeHostImpl::FrameData* frame) { |
- TRACE_EVENT0("cc", "SingleThreadProxy::CommitAndComposite"); |
- DCHECK(Proxy::IsMainThread()); |
- |
- if (!layer_tree_host_->InitializeOutputSurfaceIfNeeded()) |
- return false; |
- |
- 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()); |
+bool SingleThreadProxy::ShouldComposite() const { |
+ DCHECK(Proxy::IsImplThread()); |
+ return scheduler_on_impl_thread_->WillDrawIfNeeded(); |
+} |
- layer_tree_host_->WillCommit(); |
+void SingleThreadProxy::UpdateBackgroundAnimateTicking() { |
+ DCHECK(Proxy::IsImplThread()); |
+ layer_tree_host_impl_->UpdateBackgroundAnimateTicking( |
+ !ShouldComposite() && layer_tree_host_impl_->active_tree()->root_layer()); |
+} |
+scoped_refptr<ContextProvider> SingleThreadProxy::OffscreenContextProvider() { |
scoped_refptr<ContextProvider> offscreen_context_provider; |
if (renderer_capabilities_for_main_thread_.using_offscreen_context3d && |
layer_tree_host_->needs_offscreen_context()) { |
@@ -480,30 +531,10 @@ bool SingleThreadProxy::CommitAndComposite( |
if (offscreen_context_provider.get()) |
created_offscreen_context_provider_ = true; |
} |
- |
- DoCommit(queue.Pass()); |
- bool result = DoComposite(offscreen_context_provider, |
- frame_begin_time, |
- device_viewport_damage_rect, |
- for_readback, |
- frame); |
- layer_tree_host_->DidBeginMainFrame(); |
- return result; |
-} |
- |
-bool SingleThreadProxy::ShouldComposite() const { |
- DCHECK(Proxy::IsImplThread()); |
- return layer_tree_host_impl_->visible() && |
- layer_tree_host_impl_->CanDraw(); |
+ return offscreen_context_provider; |
} |
-void SingleThreadProxy::UpdateBackgroundAnimateTicking() { |
- DCHECK(Proxy::IsImplThread()); |
- layer_tree_host_impl_->UpdateBackgroundAnimateTicking( |
- !ShouldComposite() && layer_tree_host_impl_->active_tree()->root_layer()); |
-} |
- |
-bool SingleThreadProxy::DoComposite( |
+DrawSwapReadbackResult::DrawResult SingleThreadProxy::DoComposite( |
scoped_refptr<ContextProvider> offscreen_context_provider, |
base::TimeTicks frame_begin_time, |
const gfx::Rect& device_viewport_damage_rect, |
@@ -528,7 +559,7 @@ bool SingleThreadProxy::DoComposite( |
// CanDraw() as well. |
if (!ShouldComposite() || (for_readback && !can_do_readback)) { |
UpdateBackgroundAnimateTicking(); |
- return false; |
+ return DrawSwapReadbackResult::DRAW_ABORTED_CANT_DRAW; |
} |
layer_tree_host_impl_->Animate( |
@@ -554,14 +585,15 @@ bool SingleThreadProxy::DoComposite( |
layer_tree_host_impl_->offscreen_context_provider(); |
if (offscreen_contexts) |
offscreen_contexts->VerifyContexts(); |
- layer_tree_host_->DidLoseOutputSurface(); |
- return false; |
+ DidLoseOutputSurfaceOnImplThread(); |
+ if (for_readback) |
+ return DrawSwapReadbackResult::DRAW_ABORTED_CONTEXT_LOST; |
} |
- return true; |
+ return DrawSwapReadbackResult::DRAW_SUCCESS; |
} |
-void SingleThreadProxy::DidSwapFrame() { |
+void SingleThreadProxy::DidCommitAndDrawFrame() { |
if (next_frame_is_newly_committed_frame_) { |
next_frame_is_newly_committed_frame_ = false; |
layer_tree_host_->DidCommitAndDrawFrame(); |
@@ -570,4 +602,160 @@ void SingleThreadProxy::DidSwapFrame() { |
bool SingleThreadProxy::CommitPendingForTesting() { return false; } |
+scoped_ptr<base::Value> SingleThreadProxy::SchedulerStateAsValueForTesting() { |
+ DebugScopedSetImplThread impl(this); |
+ return scheduler_on_impl_thread_->StateAsValue().Pass(); |
+} |
+ |
+void SingleThreadProxy::SetNeedsBeginImplFrame(bool enable) { |
+ if (OutputSurface* surface = layer_tree_host_impl_->output_surface()) |
+ surface->SetNeedsBeginImplFrame(enable); |
+} |
+ |
+void SingleThreadProxy::ScheduledActionSendBeginMainFrame() { |
+ if (defer_commits_) { |
+ DCHECK(!finish_commit_deferred_); |
+ finish_commit_deferred_ = true; |
+ return; |
+ } |
+ timing_history_.DidBeginMainFrame(); |
+ |
+ // This is poorly named, but tells the scheduler that we are ready to |
+ // start the commit. In threaded mode, this is when the uploads are done. |
+ // In single-threaded mode, it doesn't really matter. Doing no work here |
+ // and all the work in commit prevents needless carrying of state (like |
+ // the upload queue) from BeginMainFrame to commit. |
+ scheduler_on_impl_thread_->FinishCommit(); |
+} |
+ |
+DrawSwapReadbackResult |
+SingleThreadProxy::ScheduledActionDrawAndSwapIfPossible() { |
+ bool do_commit = false; |
+ bool for_readback = false; |
+ gfx::Rect device_viewport_damage_rect; |
+ return CommitAndCompositeInternal(gfx::FrameTime::Now(), |
+ device_viewport_damage_rect, |
+ do_commit, |
+ for_readback); |
+} |
+ |
+DrawSwapReadbackResult SingleThreadProxy::ScheduledActionDrawAndSwapForced() { |
+ return ScheduledActionDrawAndSwapIfPossible(); |
+} |
+ |
+DrawSwapReadbackResult SingleThreadProxy::ScheduledActionDrawAndReadback() { |
+ // The SingleThreadProxy never asks for a commit for readback, |
+ // so this should never happen. |
+ NOTREACHED(); |
+ DrawSwapReadbackResult result; |
+ return result; |
+} |
+ |
+DrawSwapReadbackResult SingleThreadProxy::CommitAndCompositeInternal( |
+ base::TimeTicks frame_begin_time, |
+ gfx::Rect device_viewport_damage_rect, |
+ bool do_commit, |
+ bool for_readback) { |
+ DCHECK(Proxy::IsMainThread()); |
+ DrawSwapReadbackResult result; |
+ |
+ if (!layer_tree_host_->InitializeOutputSurfaceIfNeeded()) { |
+ result.draw_result = DrawSwapReadbackResult::DRAW_ABORTED_CONTEXT_LOST; |
+ return result; |
+ } |
+ |
+ if (do_commit) |
+ DoCommit(frame_begin_time); |
+ |
+ scoped_refptr<ContextProvider> offscreen_context_provider = |
+ OffscreenContextProvider(); |
danakj
2014/02/20 20:56:40
Hm ok one more question.
Is it going to be confus
enne (OOO)
2014/02/20 21:07:13
Is there an ordering issue that you're concerned a
danakj
2014/02/20 21:09:47
Just consistency. It comes to mind because when wr
|
+ LayerTreeHostImpl::FrameData frame; |
+ timing_history_.DidStartDrawing(); |
+ result.draw_result = DoComposite(offscreen_context_provider, |
+ frame_begin_time, |
+ device_viewport_damage_rect, |
+ for_readback, |
+ &frame); |
+ if (result.draw_result != DrawSwapReadbackResult::DRAW_SUCCESS) |
+ return result; |
+ |
+ timing_history_.DidFinishDrawing(); |
+ |
+ result.did_readback = for_readback; |
+ |
+ { |
+ 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; |
+ result.did_swap = layer_tree_host_impl_->SwapBuffers(frame); |
+ } |
+ |
+ DidCommitAndDrawFrame(); |
+ |
+ return result; |
+} |
+ |
+void SingleThreadProxy::ScheduledActionCommit() { |
+ DebugScopedSetMainThread main(this); |
+ DoCommit(gfx::FrameTime::Now()); |
+} |
+ |
+void SingleThreadProxy::ScheduledActionUpdateVisibleTiles() { |
+ // Impl-side painting only. |
+ NOTREACHED(); |
+} |
+ |
+void SingleThreadProxy::ScheduledActionActivatePendingTree() { |
+ // Impl-side painting only. |
+ NOTREACHED(); |
+} |
+ |
+void SingleThreadProxy::ScheduledActionBeginOutputSurfaceCreation() { |
+ DebugScopedSetMainThread main(this); |
+ layer_tree_host_->InitializeOutputSurfaceIfNeeded(); |
+} |
+ |
+void SingleThreadProxy::ScheduledActionAcquireLayerTexturesForMainThread() { |
+ scheduler_on_impl_thread_->SetMainThreadNeedsLayerTextures(); |
+} |
+ |
+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::PostBeginImplFrameDeadline(const base::Closure& closure, |
+ base::TimeTicks deadline) { |
+ base::TimeDelta delta = deadline - gfx::FrameTime::Now(); |
+ if (delta <= base::TimeDelta()) |
+ delta = base::TimeDelta(); |
+ Proxy::MainThreadTaskRunner()->PostDelayedTask(FROM_HERE, closure, delta); |
+} |
+ |
+void SingleThreadProxy::DidBeginImplFrameDeadline() { |
+ layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame(); |
+} |
+ |
} // namespace cc |