Commit d30a3134 authored by danakj@chromium.org's avatar danakj@chromium.org

cc: Stop blocking the main thread in CreateAndInitializeOutputSurface.

The ThreadProxy does not need to block the main thread anymore, instead
have it post back DidInitializeOutputSurface() with the result of the
process.

We would delete all contents textures on the compositor thread during
OutputSurface creation, which doesn't really make sense, cuz the
ResourceProvider won't be the same one anymore, and this required
blocking the thread.

We also notified the main thread that the OutputSurface was lost when
creating the new output surface.

Instead, post a DidLoseOutputSurface() to the main thread to inform
the LayerTreeHost right away, and have that block and clean up
the contents textures immediately (to be removed when we always do
impl-side painting).

R=enne
BUG=374287

Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=272276

Review URL: https://codereview.chromium.org/287193003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@276921 0039d316-1c4b-4281-b951-d872f2087c98
parent 0afe6315
...@@ -94,9 +94,6 @@ class CC_EXPORT Scheduler { ...@@ -94,9 +94,6 @@ class CC_EXPORT Scheduler {
void DidManageTiles(); void DidManageTiles();
void DidLoseOutputSurface(); void DidLoseOutputSurface();
void DidCreateAndInitializeOutputSurface(); void DidCreateAndInitializeOutputSurface();
bool HasInitializedOutputSurface() const {
return state_machine_.HasInitializedOutputSurface();
}
bool CommitPending() const { return state_machine_.CommitPending(); } bool CommitPending() const { return state_machine_.CommitPending(); }
bool RedrawPending() const { return state_machine_.RedrawPending(); } bool RedrawPending() const { return state_machine_.RedrawPending(); }
......
...@@ -198,40 +198,59 @@ void ThreadProxy::UpdateBackgroundAnimateTicking() { ...@@ -198,40 +198,59 @@ void ThreadProxy::UpdateBackgroundAnimateTicking() {
impl().animations_frozen_until_next_draw = false; impl().animations_frozen_until_next_draw = false;
} }
void ThreadProxy::DoCreateAndInitializeOutputSurface() { void ThreadProxy::DidLoseOutputSurface() {
TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurface");
DCHECK(IsMainThread());
layer_tree_host()->DidLoseOutputSurface();
{
DebugScopedSetMainThreadBlocked main_thread_blocked(this);
// Return lost resources to their owners immediately.
BlockingTaskRunner::CapturePostTasks blocked;
CompletionEvent completion;
Proxy::ImplThreadTaskRunner()->PostTask(
FROM_HERE,
base::Bind(&ThreadProxy::DeleteContentsTexturesOnImplThread,
impl_thread_weak_ptr_,
&completion));
completion.Wait();
}
}
void ThreadProxy::CreateAndInitializeOutputSurface() {
TRACE_EVENT0("cc", "ThreadProxy::DoCreateAndInitializeOutputSurface"); TRACE_EVENT0("cc", "ThreadProxy::DoCreateAndInitializeOutputSurface");
DCHECK(IsMainThread()); DCHECK(IsMainThread());
scoped_ptr<OutputSurface> output_surface = scoped_ptr<OutputSurface> output_surface =
layer_tree_host()->CreateOutputSurface(); layer_tree_host()->CreateOutputSurface();
RendererCapabilities capabilities; if (output_surface) {
bool success = !!output_surface;
if (success) {
// 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);
Proxy::ImplThreadTaskRunner()->PostTask( Proxy::ImplThreadTaskRunner()->PostTask(
FROM_HERE, FROM_HERE,
base::Bind(&ThreadProxy::InitializeOutputSurfaceOnImplThread, base::Bind(&ThreadProxy::InitializeOutputSurfaceOnImplThread,
impl_thread_weak_ptr_, impl_thread_weak_ptr_,
&completion, base::Passed(&output_surface)));
base::Passed(&output_surface), return;
&success,
&capabilities));
completion.Wait();
} }
DidInitializeOutputSurface(false, RendererCapabilities());
}
void ThreadProxy::DidInitializeOutputSurface(
bool success,
const RendererCapabilities& capabilities) {
TRACE_EVENT0("cc", "ThreadProxy::DidInitializeOutputSurface");
DCHECK(IsMainThread());
main().renderer_capabilities_main_thread_copy = capabilities; main().renderer_capabilities_main_thread_copy = capabilities;
layer_tree_host()->OnCreateAndInitializeOutputSurfaceAttempted(success); layer_tree_host()->OnCreateAndInitializeOutputSurfaceAttempted(success);
if (success) { if (!success) {
main().output_surface_creation_callback.Cancel();
} else if (!main().output_surface_creation_callback.IsCancelled()) {
Proxy::MainThreadTaskRunner()->PostTask( Proxy::MainThreadTaskRunner()->PostTask(
FROM_HERE, main().output_surface_creation_callback.callback()); FROM_HERE,
base::Bind(&ThreadProxy::CreateAndInitializeOutputSurface,
main_thread_weak_ptr_));
} }
} }
...@@ -312,6 +331,9 @@ void ThreadProxy::CheckOutputSurfaceStatusOnImplThread() { ...@@ -312,6 +331,9 @@ void ThreadProxy::CheckOutputSurfaceStatusOnImplThread() {
DCHECK(IsImplThread()); DCHECK(IsImplThread());
if (!impl().layer_tree_host_impl->IsContextLost()) if (!impl().layer_tree_host_impl->IsContextLost())
return; return;
Proxy::MainThreadTaskRunner()->PostTask(
FROM_HERE,
base::Bind(&ThreadProxy::DidLoseOutputSurface, main_thread_weak_ptr_));
impl().scheduler->DidLoseOutputSurface(); impl().scheduler->DidLoseOutputSurface();
} }
...@@ -727,23 +749,11 @@ void ThreadProxy::BeginMainFrame( ...@@ -727,23 +749,11 @@ void ThreadProxy::BeginMainFrame(
// swap promises. // swap promises.
SwapPromiseChecker swap_promise_checker(layer_tree_host()); SwapPromiseChecker swap_promise_checker(layer_tree_host());
// Do not notify the impl thread of commit requests that occur during main().commit_requested = false;
// the apply/animate/layout part of the BeginMainFrameAndCommit process since main().commit_request_sent_to_impl_thread = false;
// 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;
// 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().animate_requested = false; main().animate_requested = false;
if (!layer_tree_host()->visible()) { if (!layer_tree_host()->visible()) {
main().commit_requested = false;
main().commit_request_sent_to_impl_thread = false;
TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD); TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD);
bool did_handle = false; bool did_handle = false;
Proxy::ImplThreadTaskRunner()->PostTask( Proxy::ImplThreadTaskRunner()->PostTask(
...@@ -754,6 +764,29 @@ void ThreadProxy::BeginMainFrame( ...@@ -754,6 +764,29 @@ void ThreadProxy::BeginMainFrame(
return; return;
} }
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); layer_tree_host()->ApplyScrollAndScale(*begin_main_frame_state->scroll_info);
layer_tree_host()->WillBeginMainFrame(); layer_tree_host()->WillBeginMainFrame();
...@@ -1195,42 +1228,6 @@ void ThreadProxy::SetAnimationEvents(scoped_ptr<AnimationEventsVector> events) { ...@@ -1195,42 +1228,6 @@ void ThreadProxy::SetAnimationEvents(scoped_ptr<AnimationEventsVector> events) {
layer_tree_host()->SetAnimationEvents(events.Pass()); layer_tree_host()->SetAnimationEvents(events.Pass());
} }
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();
}
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) { void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) {
TRACE_EVENT0("cc", "ThreadProxy::InitializeImplOnImplThread"); TRACE_EVENT0("cc", "ThreadProxy::InitializeImplOnImplThread");
DCHECK(IsImplThread()); DCHECK(IsImplThread());
...@@ -1263,31 +1260,38 @@ void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) { ...@@ -1263,31 +1260,38 @@ void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) {
completion->Signal(); completion->Signal();
} }
void ThreadProxy::InitializeOutputSurfaceOnImplThread( void ThreadProxy::DeleteContentsTexturesOnImplThread(
CompletionEvent* completion, CompletionEvent* completion) {
scoped_ptr<OutputSurface> output_surface, TRACE_EVENT0("cc", "ThreadProxy::DeleteContentsTexturesOnImplThread");
bool* success,
RendererCapabilities* capabilities) {
TRACE_EVENT0("cc", "ThreadProxy::InitializeOutputSurfaceOnImplThread");
DCHECK(IsImplThread()); DCHECK(IsImplThread());
DCHECK(IsMainThreadBlocked()); DCHECK(IsMainThreadBlocked());
DCHECK(success);
DCHECK(capabilities);
layer_tree_host()->DeleteContentsTexturesOnImplThread( layer_tree_host()->DeleteContentsTexturesOnImplThread(
impl().layer_tree_host_impl->resource_provider()); impl().layer_tree_host_impl->resource_provider());
completion->Signal();
}
*success = void ThreadProxy::InitializeOutputSurfaceOnImplThread(
impl().layer_tree_host_impl->InitializeRenderer(output_surface.Pass()); scoped_ptr<OutputSurface> output_surface) {
TRACE_EVENT0("cc", "ThreadProxy::InitializeOutputSurfaceOnImplThread");
DCHECK(IsImplThread());
if (*success) { LayerTreeHostImpl* host_impl = impl().layer_tree_host_impl.get();
*capabilities = impl() bool success = host_impl->InitializeRenderer(output_surface.Pass());
.layer_tree_host_impl->GetRendererCapabilities() RendererCapabilities capabilities;
.MainThreadCapabilities(); if (success) {
impl().scheduler->DidCreateAndInitializeOutputSurface(); capabilities =
host_impl->GetRendererCapabilities().MainThreadCapabilities();
} }
completion->Signal(); Proxy::MainThreadTaskRunner()->PostTask(
FROM_HERE,
base::Bind(&ThreadProxy::DidInitializeOutputSurface,
main_thread_weak_ptr_,
success,
capabilities));
if (success)
impl().scheduler->DidCreateAndInitializeOutputSurface();
} }
void ThreadProxy::FinishGLOnImplThread(CompletionEvent* completion) { void ThreadProxy::FinishGLOnImplThread(CompletionEvent* completion) {
...@@ -1301,6 +1305,7 @@ void ThreadProxy::FinishGLOnImplThread(CompletionEvent* completion) { ...@@ -1301,6 +1305,7 @@ void ThreadProxy::FinishGLOnImplThread(CompletionEvent* completion) {
void ThreadProxy::LayerTreeHostClosedOnImplThread(CompletionEvent* completion) { void ThreadProxy::LayerTreeHostClosedOnImplThread(CompletionEvent* completion) {
TRACE_EVENT0("cc", "ThreadProxy::LayerTreeHostClosedOnImplThread"); TRACE_EVENT0("cc", "ThreadProxy::LayerTreeHostClosedOnImplThread");
DCHECK(IsImplThread()); DCHECK(IsImplThread());
DCHECK(IsMainThreadBlocked());
layer_tree_host()->DeleteContentsTexturesOnImplThread( layer_tree_host()->DeleteContentsTexturesOnImplThread(
impl().layer_tree_host_impl->resource_provider()); impl().layer_tree_host_impl->resource_provider());
impl().current_resource_update_controller.reset(); impl().current_resource_update_controller.reset();
......
...@@ -72,7 +72,6 @@ class CC_EXPORT ThreadProxy : public Proxy, ...@@ -72,7 +72,6 @@ class CC_EXPORT ThreadProxy : public Proxy,
bool can_cancel_commit; bool can_cancel_commit;
bool defer_commits; bool defer_commits;
base::CancelableClosure output_surface_creation_callback;
RendererCapabilities renderer_capabilities_main_thread_copy; RendererCapabilities renderer_capabilities_main_thread_copy;
scoped_ptr<BeginMainFrameAndCommitState> pending_deferred_commit; scoped_ptr<BeginMainFrameAndCommitState> pending_deferred_commit;
...@@ -242,8 +241,10 @@ class CC_EXPORT ThreadProxy : public Proxy, ...@@ -242,8 +241,10 @@ class CC_EXPORT ThreadProxy : public Proxy,
void DidCommitAndDrawFrame(); void DidCommitAndDrawFrame();
void DidCompleteSwapBuffers(); void DidCompleteSwapBuffers();
void SetAnimationEvents(scoped_ptr<AnimationEventsVector> queue); void SetAnimationEvents(scoped_ptr<AnimationEventsVector> queue);
void DidLoseOutputSurface();
void CreateAndInitializeOutputSurface(); void CreateAndInitializeOutputSurface();
void DoCreateAndInitializeOutputSurface(); void DidInitializeOutputSurface(bool success,
const RendererCapabilities& capabilities);
void SendCommitRequestToImplThreadIfNeeded(); void SendCommitRequestToImplThreadIfNeeded();
// Called on impl thread. // Called on impl thread.
...@@ -261,11 +262,9 @@ class CC_EXPORT ThreadProxy : public Proxy, ...@@ -261,11 +262,9 @@ class CC_EXPORT ThreadProxy : public Proxy,
void HasInitializedOutputSurfaceOnImplThread( void HasInitializedOutputSurfaceOnImplThread(
CompletionEvent* completion, CompletionEvent* completion,
bool* has_initialized_output_surface); bool* has_initialized_output_surface);
virtual void InitializeOutputSurfaceOnImplThread( void DeleteContentsTexturesOnImplThread(CompletionEvent* completion);
CompletionEvent* completion, void InitializeOutputSurfaceOnImplThread(
scoped_ptr<OutputSurface> output_surface, scoped_ptr<OutputSurface> output_surface);
bool* success,
RendererCapabilities* capabilities);
void FinishGLOnImplThread(CompletionEvent* completion); void FinishGLOnImplThread(CompletionEvent* completion);
void LayerTreeHostClosedOnImplThread(CompletionEvent* completion); void LayerTreeHostClosedOnImplThread(CompletionEvent* completion);
DrawResult DrawSwapInternal(bool forced_draw); DrawResult DrawSwapInternal(bool forced_draw);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment