Index: cc/output/output_surface.cc |
diff --git a/cc/output/output_surface.cc b/cc/output/output_surface.cc |
index 0786d660d4a58a3e24c03dabc3411f9d3e08cd9a..a597a87d8456bc65f3ce763d469db9e7e776ed7f 100644 |
--- a/cc/output/output_surface.cc |
+++ b/cc/output/output_surface.cc |
@@ -107,6 +107,10 @@ |
context_provider_->SetMemoryPolicyChangedCallback( |
ContextProvider::MemoryPolicyChangedCallback()); |
} |
+ if (worker_context_provider_.get()) { |
+ worker_context_provider_->SetLostContextCallback( |
+ ContextProvider::LostContextCallback()); |
+ } |
} |
bool OutputSurface::HasExternalStencilTest() const { |
@@ -130,8 +134,14 @@ |
if (success && worker_context_provider_.get()) { |
success = worker_context_provider_->BindToCurrentThread(); |
- if (success) |
+ if (success) { |
worker_context_provider_->SetupLock(); |
+ // The destructor resets the context lost callback, so base::Unretained |
+ // is safe, as long as the worker threads stop using the context before |
+ // the output surface is destroyed. |
+ worker_context_provider_->SetLostContextCallback(base::Bind( |
+ &OutputSurface::DidLoseOutputSurface, base::Unretained(this))); |
+ } |
} |
if (!success) |
@@ -207,7 +217,11 @@ |
"OutputSurface::SetWorkerContextShouldAggressivelyFreeResources", |
"aggressively_free_resources", aggressively_free_resources); |
if (auto* context_provider = worker_context_provider()) { |
- ContextProvider::ScopedContextLock scoped_context(context_provider); |
+ // The context lock must be held while accessing the worker context. |
+ base::AutoLock context_lock(*context_provider->GetLock()); |
+ |
+ // Allow context to bind to current thread. |
+ context_provider->DetachFromThread(); |
if (aggressively_free_resources) { |
context_provider->DeleteCachedResources(); |
@@ -217,6 +231,9 @@ |
context_support->SetAggressivelyFreeResources( |
aggressively_free_resources); |
} |
+ |
+ // Allow context to bind to other threads. |
+ context_provider->DetachFromThread(); |
} |
} |