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..bc404f5d49a9da05a590ac026861823d99d6db13 100644 |
--- a/cc/trees/single_thread_proxy.cc |
+++ b/cc/trees/single_thread_proxy.cc |
@@ -34,7 +34,9 @@ SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host, |
client_(client), |
created_offscreen_context_provider_(false), |
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); |
@@ -42,11 +44,19 @@ SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host, |
// Impl-side painting not supported without threaded compositing. |
CHECK(!layer_tree_host->settings().impl_side_painting) |
<< "Threaded compositing must be enabled to use impl-side painting."; |
+ |
+ output_surface_creation_callback_.Reset( |
+ base::Bind(&SingleThreadProxy::CreateAndInitializeOutputSurface, |
+ base::Unretained(this))); |
} |
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 +70,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 +110,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 +176,21 @@ 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(); |
+ Proxy::MainThreadTaskRunner()->PostTask( |
+ FROM_HERE, output_surface_creation_callback_.callback()); |
danakj
2014/02/19 20:42:39
Looks like there's no reason to use a CancelableCa
enne (OOO)
2014/02/20 00:35:44
This is because the STP could be destroyed before
danakj
2014/02/20 19:30:55
I see, ya I prefer a weak ptr factory. That'll mak
enne (OOO)
2014/02/20 20:01:39
Done.
|
} |
} |
@@ -181,18 +203,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(); |
danakj
2014/02/19 20:42:39
Is it a TODO to support SetNeedsUpdateLayers ie ca
enne (OOO)
2014/02/20 00:35:44
The cancellable commit is really about handling of
danakj
2014/02/20 19:30:55
Or possibly occluded invalidations? That will be s
enne (OOO)
2014/02/20 20:01:39
These don't happen with impl-side painting, so...
danakj
2014/02/20 20:06:34
2014/02/20 20:01:39, enne wrote:
|
} |
-void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) { |
+void SingleThreadProxy::DoCommit(base::TimeTicks frame_begin_time) { |
TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit"); |
- DCHECK(Proxy::IsMainThread()); |
+ // DCHECK(Proxy::IsMainThread()); |
danakj
2014/02/19 20:42:39
commented out? impl and main blocked?
enne (OOO)
2014/02/20 00:35:44
Uncommented.
|
+ 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 +268,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 +286,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; |
danakj
2014/02/19 20:42:39
I noticed that ThreadProxy sets scheduler visibili
enne (OOO)
2014/02/20 00:35:44
SingleThreadProxy handles it immediately, rather t
danakj
2014/02/20 19:30:55
ThreadProxy does also, it passes it over to SetVis
enne (OOO)
2014/02/20 20:01:39
That's possible. Maybe the scheduler needs to be
|
} |
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 +343,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 +354,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 +383,7 @@ void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() { |
} |
void SingleThreadProxy::SetNeedsCommitOnImplThread() { |
- client_->ScheduleComposite(); |
+ scheduler_on_impl_thread_->SetNeedsCommit(); |
} |
void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread( |
@@ -372,8 +432,15 @@ bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; } |
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 did lose output surface as the scheduler |
danakj
2014/02/19 20:42:39
"before did lose output surface" -> "before we not
enne (OOO)
2014/02/20 00:35:44
Done.
|
+ // may try to recreate the output surface if already in begin impl frame |
danakj
2014/02/19 20:42:39
"if already in begin impl frame idle"
i know all
enne (OOO)
2014/02/20 00:35:44
"begin impl frame idle" => BEGIN_IMPL_FRAME_STATE_
|
+ // idle. |
+ layer_tree_host_->DidLoseOutputSurface(); |
+ } |
+ |
+ scheduler_on_impl_thread_->DidLoseOutputSurface(); |
danakj
2014/02/19 20:42:39
usually calling the scheduler is the last thing in
enne (OOO)
2014/02/20 00:35:44
Seems safer. Done.
|
client_->DidAbortSwapBuffers(); |
danakj
2014/02/19 20:42:39
This is going to be.. weird.. I think. The schedu
enne (OOO)
2014/02/20 00:35:44
I see this getting used in:
* render_widget_compos
danakj
2014/02/20 19:30:55
Uh, hm. Really not clear why losing the graphics c
enne (OOO)
2014/02/20 20:01:39
Done.
|
} |
@@ -386,34 +453,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 +493,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 layer_tree_host_impl_->visible() && layer_tree_host_impl_->CanDraw(); |
danakj
2014/02/19 20:42:39
why is this based on visible and not on Scheduler:
enne (OOO)
2014/02/20 00:35:44
Done.
|
+} |
- 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 +517,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(); |
-} |
- |
-void SingleThreadProxy::UpdateBackgroundAnimateTicking() { |
- DCHECK(Proxy::IsImplThread()); |
- layer_tree_host_impl_->UpdateBackgroundAnimateTicking( |
- !ShouldComposite() && layer_tree_host_impl_->active_tree()->root_layer()); |
+ return offscreen_context_provider; |
} |
-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 +545,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 +571,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 +588,157 @@ 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(); |
+ 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() {} |
danakj
2014/02/19 20:42:39
NOTREACHED Impl-side painting only?
enne (OOO)
2014/02/20 00:35:44
Done. Did this for a few other functions too.
|
+ |
+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 |