summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cc/output/context_provider.h9
-rw-r--r--cc/test/fake_context_provider.cc42
-rw-r--r--cc/test/fake_context_provider.h19
-rw-r--r--content/browser/aura/gpu_process_transport_factory.cc80
-rw-r--r--content/browser/aura/gpu_process_transport_factory.h43
-rw-r--r--content/common/gpu/client/context_provider_command_buffer.cc49
-rw-r--r--content/common/gpu/client/context_provider_command_buffer.h24
-rw-r--r--content/renderer/render_thread_impl.cc30
-rw-r--r--content/renderer/render_thread_impl.h6
-rw-r--r--ui/compositor/context_provider_from_context_factory.cc5
-rw-r--r--ui/compositor/context_provider_from_context_factory.h1
-rw-r--r--webkit/common/gpu/context_provider_in_process.cc35
-rw-r--r--webkit/common/gpu/context_provider_in_process.h13
13 files changed, 189 insertions, 167 deletions
diff --git a/cc/output/context_provider.h b/cc/output/context_provider.h
index 3b489c7..13b7df5 100644
--- a/cc/output/context_provider.h
+++ b/cc/output/context_provider.h
@@ -5,6 +5,7 @@
#ifndef CC_OUTPUT_CONTEXT_PROVIDER_H_
#define CC_OUTPUT_CONTEXT_PROVIDER_H_
+#include "base/callback.h"
#include "base/memory/ref_counted.h"
class GrContext;
@@ -32,6 +33,14 @@ class ContextProvider : public base::RefCountedThreadSafe<ContextProvider> {
// the context inside the provider is no longer valid.
virtual bool DestroyedOnMainThread() = 0;
+ // Sets a callback to be called when the context is lost. This should be
+ // called from the same thread that the context is bound to. To avoid races,
+ // it should be called before BindToCurrentThread(), or VerifyContexts()
+ // should be called after setting the callback.
+ typedef base::Closure LostContextCallback;
+ virtual void SetLostContextCallback(
+ const LostContextCallback& lost_context_callback) = 0;
+
protected:
friend class base::RefCountedThreadSafe<ContextProvider>;
virtual ~ContextProvider() {}
diff --git a/cc/test/fake_context_provider.cc b/cc/test/fake_context_provider.cc
index e12f783..d49fa89 100644
--- a/cc/test/fake_context_provider.cc
+++ b/cc/test/fake_context_provider.cc
@@ -9,29 +9,38 @@
namespace cc {
FakeContextProvider::FakeContextProvider()
- : destroyed_(false) {
+ : bound_(false),
+ destroyed_(false) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ context_thread_checker_.DetachFromThread();
}
-FakeContextProvider::FakeContextProvider(
- const CreateCallback& create_callback)
- : create_callback_(create_callback),
- bound_(false),
- destroyed_(false) {
+FakeContextProvider::~FakeContextProvider() {
+ DCHECK(main_thread_checker_.CalledOnValidThread() ||
+ context_thread_checker_.CalledOnValidThread());
}
-FakeContextProvider::~FakeContextProvider() {}
+bool FakeContextProvider::InitializeOnMainThread(
+ const CreateCallback& create_callback) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
-bool FakeContextProvider::InitializeOnMainThread() {
DCHECK(!context3d_);
-
- if (create_callback_.is_null())
+ if (create_callback.is_null())
context3d_ = TestWebGraphicsContext3D::Create().Pass();
else
- context3d_ = create_callback_.Run();
+ context3d_ = create_callback.Run();
return context3d_;
}
bool FakeContextProvider::BindToCurrentThread() {
+ DCHECK(context3d_);
+
+ // This is called on the thread the context will be used.
+ DCHECK(context_thread_checker_.CalledOnValidThread());
+
+ if (bound_)
+ return true;
+
bound_ = true;
if (!context3d_->makeContextCurrent()) {
base::AutoLock lock(destroyed_lock_);
@@ -44,12 +53,14 @@ bool FakeContextProvider::BindToCurrentThread() {
WebKit::WebGraphicsContext3D* FakeContextProvider::Context3d() {
DCHECK(context3d_);
DCHECK(bound_);
+ DCHECK(context_thread_checker_.CalledOnValidThread());
return context3d_.get();
}
class GrContext* FakeContextProvider::GrContext() {
DCHECK(context3d_);
DCHECK(bound_);
+ DCHECK(context_thread_checker_.CalledOnValidThread());
// TODO(danakj): Make a fake GrContext.
return NULL;
@@ -58,6 +69,7 @@ class GrContext* FakeContextProvider::GrContext() {
void FakeContextProvider::VerifyContexts() {
DCHECK(context3d_);
DCHECK(bound_);
+ DCHECK(context_thread_checker_.CalledOnValidThread());
if (context3d_->isContextLost()) {
base::AutoLock lock(destroyed_lock_);
@@ -66,8 +78,16 @@ void FakeContextProvider::VerifyContexts() {
}
bool FakeContextProvider::DestroyedOnMainThread() {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+
base::AutoLock lock(destroyed_lock_);
return destroyed_;
}
+void FakeContextProvider::SetLostContextCallback(
+ const LostContextCallback& cb) {
+ DCHECK(context_thread_checker_.CalledOnValidThread());
+ NOTIMPLEMENTED();
+}
+
} // namespace cc
diff --git a/cc/test/fake_context_provider.h b/cc/test/fake_context_provider.h
index 9ab1abd..4a18e4a 100644
--- a/cc/test/fake_context_provider.h
+++ b/cc/test/fake_context_provider.h
@@ -8,6 +8,7 @@
#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
+#include "base/threading/thread_checker.h"
#include "cc/output/context_provider.h"
namespace cc {
@@ -19,17 +20,13 @@ class FakeContextProvider : public cc::ContextProvider {
CreateCallback;
static scoped_refptr<FakeContextProvider> Create() {
- scoped_refptr<FakeContextProvider> provider = new FakeContextProvider();
- if (!provider->InitializeOnMainThread())
- return NULL;
- return provider;
+ return Create(CreateCallback());
}
static scoped_refptr<FakeContextProvider> Create(
const CreateCallback& create_callback) {
- scoped_refptr<FakeContextProvider> provider =
- new FakeContextProvider(create_callback);
- if (!provider->InitializeOnMainThread())
+ scoped_refptr<FakeContextProvider> provider = new FakeContextProvider;
+ if (!provider->InitializeOnMainThread(create_callback))
return NULL;
return provider;
}
@@ -39,18 +36,20 @@ class FakeContextProvider : public cc::ContextProvider {
virtual class GrContext* GrContext() OVERRIDE;
virtual void VerifyContexts() OVERRIDE;
virtual bool DestroyedOnMainThread() OVERRIDE;
+ virtual void SetLostContextCallback(const LostContextCallback& cb) OVERRIDE;
protected:
FakeContextProvider();
- explicit FakeContextProvider(const CreateCallback& create_callback);
virtual ~FakeContextProvider();
- bool InitializeOnMainThread();
+ bool InitializeOnMainThread(const CreateCallback& create_callback);
- CreateCallback create_callback_;
scoped_ptr<WebKit::WebGraphicsContext3D> context3d_;
bool bound_;
+ base::ThreadChecker main_thread_checker_;
+ base::ThreadChecker context_thread_checker_;
+
base::Lock destroyed_lock_;
bool destroyed_;
};
diff --git a/content/browser/aura/gpu_process_transport_factory.cc b/content/browser/aura/gpu_process_transport_factory.cc
index 0a4a8fa..6ac45f7 100644
--- a/content/browser/aura/gpu_process_transport_factory.cc
+++ b/content/browser/aura/gpu_process_transport_factory.cc
@@ -19,6 +19,7 @@
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/gpu/gpu_surface_tracker.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/common/gpu/client/context_provider_command_buffer.h"
#include "content/common/gpu/client/gl_helper.h"
#include "content/common/gpu/client/gpu_channel_host.h"
#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
@@ -221,6 +222,9 @@ GpuProcessTransportFactory::GpuProcessTransportFactory()
GpuProcessTransportFactory::~GpuProcessTransportFactory() {
DCHECK(per_compositor_data_.empty());
+
+ // Make sure the lost context callback doesn't try to run during destruction.
+ callback_factory_.InvalidateWeakPtrs();
}
scoped_ptr<WebGraphicsContext3DCommandBufferImpl>
@@ -397,7 +401,15 @@ scoped_refptr<cc::ContextProvider>
GpuProcessTransportFactory::OffscreenContextProviderForMainThread() {
if (!shared_contexts_main_thread_.get() ||
shared_contexts_main_thread_->DestroyedOnMainThread()) {
- shared_contexts_main_thread_ = MainThreadContextProvider::Create(this);
+ shared_contexts_main_thread_ = ContextProviderCommandBuffer::Create(
+ base::Bind(&GpuProcessTransportFactory::
+ CreateOffscreenCommandBufferContext,
+ base::Unretained(this)));
+ shared_contexts_main_thread_->SetLostContextCallback(base::Bind(
+ &GpuProcessTransportFactory::
+ OnLostMainThreadSharedContextInsideCallback,
+ callback_factory_.GetWeakPtr()));
+
if (shared_contexts_main_thread_.get() &&
!shared_contexts_main_thread_->BindToCurrentThread())
shared_contexts_main_thread_ = NULL;
@@ -409,8 +421,10 @@ scoped_refptr<cc::ContextProvider>
GpuProcessTransportFactory::OffscreenContextProviderForCompositorThread() {
if (!shared_contexts_compositor_thread_.get() ||
shared_contexts_compositor_thread_->DestroyedOnMainThread()) {
- shared_contexts_compositor_thread_ =
- CompositorThreadContextProvider::Create(this);
+ shared_contexts_compositor_thread_ = ContextProviderCommandBuffer::Create(
+ base::Bind(&GpuProcessTransportFactory::
+ CreateOffscreenCommandBufferContext,
+ base::Unretained(this)));
}
return shared_contexts_compositor_thread_;
}
@@ -480,64 +494,16 @@ GpuProcessTransportFactory::CreateContextCommon(
return context.Pass();
}
-// static
-scoped_refptr<GpuProcessTransportFactory::MainThreadContextProvider>
-GpuProcessTransportFactory::MainThreadContextProvider::Create(
- GpuProcessTransportFactory* factory) {
- scoped_refptr<MainThreadContextProvider> provider =
- new MainThreadContextProvider(factory);
- if (!provider->InitializeOnMainThread())
- return NULL;
- return provider;
-}
-
-GpuProcessTransportFactory::MainThreadContextProvider::
- MainThreadContextProvider(GpuProcessTransportFactory* factory)
- : factory_(factory) {}
-
-GpuProcessTransportFactory::MainThreadContextProvider::
- ~MainThreadContextProvider() {}
-
-scoped_ptr<WebGraphicsContext3DCommandBufferImpl>
-GpuProcessTransportFactory::MainThreadContextProvider::
- CreateOffscreenContext3d() {
- return factory_->CreateOffscreenCommandBufferContext();
+void GpuProcessTransportFactory::CreateSharedContextLazy() {
+ scoped_refptr<cc::ContextProvider> provider =
+ OffscreenContextProviderForMainThread();
}
-void GpuProcessTransportFactory::MainThreadContextProvider::OnLostContext() {
+void GpuProcessTransportFactory::OnLostMainThreadSharedContextInsideCallback() {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&GpuProcessTransportFactory::OnLostMainThreadSharedContext,
- factory_->callback_factory_.GetWeakPtr()));
-}
-
-// static
-scoped_refptr<GpuProcessTransportFactory::CompositorThreadContextProvider>
-GpuProcessTransportFactory::CompositorThreadContextProvider::Create(
- GpuProcessTransportFactory* factory) {
- scoped_refptr<CompositorThreadContextProvider> provider =
- new CompositorThreadContextProvider(factory);
- if (!provider->InitializeOnMainThread())
- return NULL;
- return provider;
-}
-
-GpuProcessTransportFactory::CompositorThreadContextProvider::
- CompositorThreadContextProvider(GpuProcessTransportFactory* factory)
- : factory_(factory) {}
-
-GpuProcessTransportFactory::CompositorThreadContextProvider::
- ~CompositorThreadContextProvider() {}
-
-scoped_ptr<WebGraphicsContext3DCommandBufferImpl>
-GpuProcessTransportFactory::CompositorThreadContextProvider::
- CreateOffscreenContext3d() {
- return factory_->CreateOffscreenCommandBufferContext();
-}
-
-void GpuProcessTransportFactory::CreateSharedContextLazy() {
- scoped_refptr<cc::ContextProvider> provider =
- OffscreenContextProviderForMainThread();
+ callback_factory_.GetWeakPtr()));
}
void GpuProcessTransportFactory::OnLostMainThreadSharedContext() {
@@ -545,7 +511,7 @@ void GpuProcessTransportFactory::OnLostMainThreadSharedContext() {
// Keep old resources around while we call the observers, but ensure that
// new resources are created if needed.
- scoped_refptr<MainThreadContextProvider> old_contexts_main_thread =
+ scoped_refptr<ContextProviderCommandBuffer> old_contexts_main_thread =
shared_contexts_main_thread_;
shared_contexts_main_thread_ = NULL;
diff --git a/content/browser/aura/gpu_process_transport_factory.h b/content/browser/aura/gpu_process_transport_factory.h
index 276316f..9e40b5c 100644
--- a/content/browser/aura/gpu_process_transport_factory.h
+++ b/content/browser/aura/gpu_process_transport_factory.h
@@ -13,13 +13,13 @@
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "content/browser/aura/image_transport_factory.h"
-#include "content/common/gpu/client/context_provider_command_buffer.h"
#include "ui/compositor/compositor.h"
namespace content {
class BrowserCompositorOutputSurface;
class BrowserCompositorOutputSurfaceProxy;
class CompositorSwapClient;
+class ContextProviderCommandBuffer;
class ReflectorImpl;
class WebGraphicsContext3DCommandBufferImpl;
class WebGraphicsContext3DSwapBuffersClient;
@@ -79,50 +79,15 @@ class GpuProcessTransportFactory
const base::WeakPtr<WebGraphicsContext3DSwapBuffersClient>& swap_client,
int surface_id);
- class MainThreadContextProvider : public ContextProviderCommandBuffer {
- public:
- static scoped_refptr<MainThreadContextProvider> Create(
- GpuProcessTransportFactory* factory);
-
- protected:
- explicit MainThreadContextProvider(GpuProcessTransportFactory* factory);
- virtual ~MainThreadContextProvider();
-
- // ContextProviderCommandBuffer implementation.
- virtual scoped_ptr<WebGraphicsContext3DCommandBufferImpl>
- CreateOffscreenContext3d() OVERRIDE;
- virtual void OnLostContext() OVERRIDE;
-
- private:
- GpuProcessTransportFactory* factory_;
- };
-
- class CompositorThreadContextProvider : public ContextProviderCommandBuffer {
- public:
- static scoped_refptr<CompositorThreadContextProvider> Create(
- GpuProcessTransportFactory* factory);
-
- protected:
- explicit CompositorThreadContextProvider(
- GpuProcessTransportFactory* factory);
- virtual ~CompositorThreadContextProvider();
-
- // ContextProviderCommandBuffer implementation.
- virtual scoped_ptr<WebGraphicsContext3DCommandBufferImpl>
- CreateOffscreenContext3d() OVERRIDE;
-
- private:
- GpuProcessTransportFactory* factory_;
- };
-
void CreateSharedContextLazy();
+ void OnLostMainThreadSharedContextInsideCallback();
void OnLostMainThreadSharedContext();
typedef std::map<ui::Compositor*, PerCompositorData*> PerCompositorDataMap;
PerCompositorDataMap per_compositor_data_;
- scoped_refptr<MainThreadContextProvider> shared_contexts_main_thread_;
- scoped_refptr<CompositorThreadContextProvider>
+ scoped_refptr<ContextProviderCommandBuffer> shared_contexts_main_thread_;
+ scoped_refptr<ContextProviderCommandBuffer>
shared_contexts_compositor_thread_;
scoped_ptr<GLHelper> gl_helper_;
ObserverList<ImageTransportFactoryObserver> observer_list_;
diff --git a/content/common/gpu/client/context_provider_command_buffer.cc b/content/common/gpu/client/context_provider_command_buffer.cc
index 6789116..96e75ad 100644
--- a/content/common/gpu/client/context_provider_command_buffer.cc
+++ b/content/common/gpu/client/context_provider_command_buffer.cc
@@ -4,6 +4,7 @@
#include "content/common/gpu/client/context_provider_command_buffer.h"
+#include "base/callback_helpers.h"
#include "webkit/common/gpu/grcontext_for_webgraphicscontext3d.h"
namespace content {
@@ -21,7 +22,7 @@ class ContextProviderCommandBuffer::LostContextCallbackProxy
}
virtual void onContextLost() {
- provider_->OnLostContextInternal();
+ provider_->OnLostContext();
}
private:
@@ -50,12 +51,26 @@ class ContextProviderCommandBuffer::MemoryAllocationCallbackProxy
ContextProviderCommandBuffer* provider_;
};
+scoped_refptr<ContextProviderCommandBuffer>
+ContextProviderCommandBuffer::Create(const CreateCallback& create_callback) {
+ scoped_refptr<ContextProviderCommandBuffer> provider =
+ new ContextProviderCommandBuffer;
+ if (!provider->InitializeOnMainThread(create_callback))
+ return NULL;
+ return provider;
+}
+
ContextProviderCommandBuffer::ContextProviderCommandBuffer()
: leak_on_destroy_(false),
destroyed_(false) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ context_thread_checker_.DetachFromThread();
}
ContextProviderCommandBuffer::~ContextProviderCommandBuffer() {
+ DCHECK(main_thread_checker_.CalledOnValidThread() ||
+ context_thread_checker_.CalledOnValidThread());
+
base::AutoLock lock(main_thread_lock_);
if (leak_on_destroy_) {
WebGraphicsContext3DCommandBufferImpl* context3d ALLOW_UNUSED =
@@ -65,15 +80,22 @@ ContextProviderCommandBuffer::~ContextProviderCommandBuffer() {
}
}
-bool ContextProviderCommandBuffer::InitializeOnMainThread() {
+bool ContextProviderCommandBuffer::InitializeOnMainThread(
+ const CreateCallback& create_callback) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+
DCHECK(!context3d_);
- context3d_ = CreateOffscreenContext3d().Pass();
+ DCHECK(!create_callback.is_null());
+ context3d_ = create_callback.Run();
return !!context3d_;
}
bool ContextProviderCommandBuffer::BindToCurrentThread() {
DCHECK(context3d_);
+ // This is called on the thread the context will be used.
+ DCHECK(context_thread_checker_.CalledOnValidThread());
+
if (lost_context_callback_proxy_)
return true;
@@ -88,6 +110,7 @@ WebGraphicsContext3DCommandBufferImpl*
ContextProviderCommandBuffer::Context3d() {
DCHECK(context3d_);
DCHECK(lost_context_callback_proxy_); // Is bound to thread.
+ DCHECK(context_thread_checker_.CalledOnValidThread());
return context3d_.get();
}
@@ -95,6 +118,7 @@ ContextProviderCommandBuffer::Context3d() {
class GrContext* ContextProviderCommandBuffer::GrContext() {
DCHECK(context3d_);
DCHECK(lost_context_callback_proxy_); // Is bound to thread.
+ DCHECK(context_thread_checker_.CalledOnValidThread());
if (gr_context_)
return gr_context_->get();
@@ -109,28 +133,41 @@ class GrContext* ContextProviderCommandBuffer::GrContext() {
void ContextProviderCommandBuffer::VerifyContexts() {
DCHECK(context3d_);
DCHECK(lost_context_callback_proxy_); // Is bound to thread.
+ DCHECK(context_thread_checker_.CalledOnValidThread());
if (context3d_->isContextLost())
- OnLostContextInternal();
+ OnLostContext();
}
-void ContextProviderCommandBuffer::OnLostContextInternal() {
+void ContextProviderCommandBuffer::OnLostContext() {
+ DCHECK(context_thread_checker_.CalledOnValidThread());
{
base::AutoLock lock(main_thread_lock_);
if (destroyed_)
return;
destroyed_ = true;
}
- OnLostContext();
+ if (!lost_context_callback_.is_null())
+ base::ResetAndReturn(&lost_context_callback_).Run();
}
bool ContextProviderCommandBuffer::DestroyedOnMainThread() {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+
base::AutoLock lock(main_thread_lock_);
return destroyed_;
}
+void ContextProviderCommandBuffer::SetLostContextCallback(
+ const LostContextCallback& lost_context_callback) {
+ DCHECK(context_thread_checker_.CalledOnValidThread());
+ DCHECK(lost_context_callback_.is_null());
+ lost_context_callback_ = lost_context_callback;
+}
+
void ContextProviderCommandBuffer::OnMemoryAllocationChanged(
bool nonzero_allocation) {
+ DCHECK(context_thread_checker_.CalledOnValidThread());
if (gr_context_)
gr_context_->SetMemoryLimit(nonzero_allocation);
}
diff --git a/content/common/gpu/client/context_provider_command_buffer.h b/content/common/gpu/client/context_provider_command_buffer.h
index acb9303..dd21499 100644
--- a/content/common/gpu/client/context_provider_command_buffer.h
+++ b/content/common/gpu/client/context_provider_command_buffer.h
@@ -7,6 +7,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
+#include "base/threading/thread_checker.h"
#include "cc/output/context_provider.h"
#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
@@ -22,11 +23,18 @@ namespace content {
// WebGraphicsContext3DCommandBufferImpl context and a GrContext.
class ContextProviderCommandBuffer : public cc::ContextProvider {
public:
+ typedef base::Callback<
+ scoped_ptr<WebGraphicsContext3DCommandBufferImpl>(void)> CreateCallback;
+ static scoped_refptr<ContextProviderCommandBuffer> Create(
+ const CreateCallback& create_callback);
+
virtual bool BindToCurrentThread() OVERRIDE;
virtual WebGraphicsContext3DCommandBufferImpl* Context3d() OVERRIDE;
virtual class GrContext* GrContext() OVERRIDE;
virtual void VerifyContexts() OVERRIDE;
virtual bool DestroyedOnMainThread() OVERRIDE;
+ virtual void SetLostContextCallback(
+ const LostContextCallback& lost_context_callback) OVERRIDE;
void set_leak_on_destroy() {
base::AutoLock lock(main_thread_lock_);
@@ -39,20 +47,20 @@ class ContextProviderCommandBuffer : public cc::ContextProvider {
// This must be called immedately after creating this object, and it should
// be thrown away if this returns false.
- bool InitializeOnMainThread();
-
- // Subclass must provide an implementation to create an offscreen context.
- virtual scoped_ptr<WebGraphicsContext3DCommandBufferImpl>
- CreateOffscreenContext3d() = 0;
+ bool InitializeOnMainThread(const CreateCallback& create_callback);
- void OnLostContextInternal();
- virtual void OnLostContext() {}
- virtual void OnMemoryAllocationChanged(bool nonzero_allocation);
+ void OnLostContext();
+ void OnMemoryAllocationChanged(bool nonzero_allocation);
private:
+ base::ThreadChecker main_thread_checker_;
+ base::ThreadChecker context_thread_checker_;
+
scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context3d_;
scoped_ptr<webkit::gpu::GrContextForWebGraphicsContext3D> gr_context_;
+ LostContextCallback lost_context_callback_;
+
base::Lock main_thread_lock_;
bool leak_on_destroy_;
bool destroyed_;
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 7adc22f..8f656a0 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -250,28 +250,6 @@ class RenderThreadImpl::GpuVDAContextLostCallback
scoped_refptr<base::MessageLoopProxy> main_message_loop_;
};
-class RenderThreadImpl::RendererContextProviderCommandBuffer
- : public ContextProviderCommandBuffer {
- public:
- static scoped_refptr<RendererContextProviderCommandBuffer> Create() {
- scoped_refptr<RendererContextProviderCommandBuffer> provider =
- new RendererContextProviderCommandBuffer();
- if (!provider->InitializeOnMainThread())
- return NULL;
- return provider;
- }
-
- protected:
- virtual ~RendererContextProviderCommandBuffer() {}
-
- virtual scoped_ptr<WebGraphicsContext3DCommandBufferImpl>
- CreateOffscreenContext3d() OVERRIDE {
- RenderThreadImpl* self = RenderThreadImpl::current();
- DCHECK(self);
- return self->CreateOffscreenContext3d().Pass();
- }
-};
-
RenderThreadImpl::HistogramCustomizer::HistogramCustomizer() {
custom_histograms_.insert("V8.MemoryExternalFragmentationTotal");
custom_histograms_.insert("V8.MemoryHeapSampleTotalCommitted");
@@ -977,7 +955,9 @@ RenderThreadImpl::OffscreenContextProviderForMainThread() {
if (!shared_contexts_main_thread_.get() ||
shared_contexts_main_thread_->DestroyedOnMainThread()) {
shared_contexts_main_thread_ =
- RendererContextProviderCommandBuffer::Create();
+ ContextProviderCommandBuffer::Create(
+ base::Bind(&RenderThreadImpl::CreateOffscreenContext3d,
+ base::Unretained(this)));
if (shared_contexts_main_thread_.get() &&
!shared_contexts_main_thread_->BindToCurrentThread())
shared_contexts_main_thread_ = NULL;
@@ -999,7 +979,9 @@ RenderThreadImpl::OffscreenContextProviderForCompositorThread() {
if (!shared_contexts_compositor_thread_.get() ||
shared_contexts_compositor_thread_->DestroyedOnMainThread()) {
shared_contexts_compositor_thread_ =
- RendererContextProviderCommandBuffer::Create();
+ ContextProviderCommandBuffer::Create(
+ base::Bind(&RenderThreadImpl::CreateOffscreenContext3d,
+ base::Unretained(this)));
}
return shared_contexts_compositor_thread_;
}
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h
index 5b3dac0..a0bda15 100644
--- a/content/renderer/render_thread_impl.h
+++ b/content/renderer/render_thread_impl.h
@@ -467,10 +467,8 @@ class CONTENT_EXPORT RenderThreadImpl : public RenderThread,
scoped_ptr<InputHandlerManager> input_handler_manager_;
scoped_refptr<IPC::ForwardingMessageFilter> compositor_output_surface_filter_;
- class RendererContextProviderCommandBuffer;
- scoped_refptr<RendererContextProviderCommandBuffer>
- shared_contexts_main_thread_;
- scoped_refptr<RendererContextProviderCommandBuffer>
+ scoped_refptr<ContextProviderCommandBuffer> shared_contexts_main_thread_;
+ scoped_refptr<ContextProviderCommandBuffer>
shared_contexts_compositor_thread_;
ObserverList<RenderProcessObserver> observers_;
diff --git a/ui/compositor/context_provider_from_context_factory.cc b/ui/compositor/context_provider_from_context_factory.cc
index c6f7790..262998a 100644
--- a/ui/compositor/context_provider_from_context_factory.cc
+++ b/ui/compositor/context_provider_from_context_factory.cc
@@ -61,6 +61,11 @@ bool ContextProviderFromContextFactory::DestroyedOnMainThread() {
return destroyed_;
}
+void ContextProviderFromContextFactory::SetLostContextCallback(
+ const LostContextCallback& cb) {
+ NOTIMPLEMENTED();
+}
+
bool ContextProviderFromContextFactory::InitializeOnMainThread() {
if (context3d_)
return true;
diff --git a/ui/compositor/context_provider_from_context_factory.h b/ui/compositor/context_provider_from_context_factory.h
index 9877ab3..57be7f4 100644
--- a/ui/compositor/context_provider_from_context_factory.h
+++ b/ui/compositor/context_provider_from_context_factory.h
@@ -24,6 +24,7 @@ class ContextProviderFromContextFactory
virtual class GrContext* GrContext() OVERRIDE;
virtual void VerifyContexts() OVERRIDE;
virtual bool DestroyedOnMainThread() OVERRIDE;
+ virtual void SetLostContextCallback(const LostContextCallback& cb) OVERRIDE;
protected:
ContextProviderFromContextFactory(ContextFactory* factory);
diff --git a/webkit/common/gpu/context_provider_in_process.cc b/webkit/common/gpu/context_provider_in_process.cc
index 5daf360..e56da80 100644
--- a/webkit/common/gpu/context_provider_in_process.cc
+++ b/webkit/common/gpu/context_provider_in_process.cc
@@ -4,6 +4,7 @@
#include "webkit/common/gpu/context_provider_in_process.h"
+#include "base/callback_helpers.h"
#include "webkit/common/gpu/grcontext_for_webgraphicscontext3d.h"
#include "webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h"
@@ -23,7 +24,7 @@ class ContextProviderInProcess::LostContextCallbackProxy
}
virtual void onContextLost() {
- provider_->OnLostContextInternal();
+ provider_->OnLostContext();
}
private:
@@ -54,12 +55,18 @@ class ContextProviderInProcess::MemoryAllocationCallbackProxy
ContextProviderInProcess::ContextProviderInProcess()
: destroyed_(false) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ context_thread_checker_.DetachFromThread();
}
-ContextProviderInProcess::~ContextProviderInProcess() {}
+ContextProviderInProcess::~ContextProviderInProcess() {
+ DCHECK(main_thread_checker_.CalledOnValidThread() ||
+ context_thread_checker_.CalledOnValidThread());
+}
bool ContextProviderInProcess::InitializeOnMainThread() {
DCHECK(!context3d_);
+ DCHECK(main_thread_checker_.CalledOnValidThread());
WebKit::WebGraphicsContext3D::Attributes attributes;
attributes.depth = false;
@@ -79,6 +86,9 @@ bool ContextProviderInProcess::InitializeOnMainThread() {
bool ContextProviderInProcess::BindToCurrentThread() {
DCHECK(context3d_);
+ // This is called on the thread the context will be used.
+ DCHECK(context_thread_checker_.CalledOnValidThread());
+
if (lost_context_callback_proxy_)
return true;
@@ -92,6 +102,7 @@ bool ContextProviderInProcess::BindToCurrentThread() {
WebKit::WebGraphicsContext3D* ContextProviderInProcess::Context3d() {
DCHECK(context3d_);
DCHECK(lost_context_callback_proxy_); // Is bound to thread.
+ DCHECK(context_thread_checker_.CalledOnValidThread());
return context3d_.get();
}
@@ -99,6 +110,7 @@ WebKit::WebGraphicsContext3D* ContextProviderInProcess::Context3d() {
class GrContext* ContextProviderInProcess::GrContext() {
DCHECK(context3d_);
DCHECK(lost_context_callback_proxy_); // Is bound to thread.
+ DCHECK(context_thread_checker_.CalledOnValidThread());
if (gr_context_)
return gr_context_->get();
@@ -113,28 +125,41 @@ class GrContext* ContextProviderInProcess::GrContext() {
void ContextProviderInProcess::VerifyContexts() {
DCHECK(context3d_);
DCHECK(lost_context_callback_proxy_); // Is bound to thread.
+ DCHECK(context_thread_checker_.CalledOnValidThread());
if (context3d_->isContextLost())
- OnLostContextInternal();
+ OnLostContext();
}
-void ContextProviderInProcess::OnLostContextInternal() {
+void ContextProviderInProcess::OnLostContext() {
+ DCHECK(context_thread_checker_.CalledOnValidThread());
{
base::AutoLock lock(destroyed_lock_);
if (destroyed_)
return;
destroyed_ = true;
}
- OnLostContext();
+ if (!lost_context_callback_.is_null())
+ base::ResetAndReturn(&lost_context_callback_).Run();
}
bool ContextProviderInProcess::DestroyedOnMainThread() {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+
base::AutoLock lock(destroyed_lock_);
return destroyed_;
}
+void ContextProviderInProcess::SetLostContextCallback(
+ const LostContextCallback& lost_context_callback) {
+ DCHECK(context_thread_checker_.CalledOnValidThread());
+ DCHECK(lost_context_callback_.is_null());
+ lost_context_callback_ = lost_context_callback;
+}
+
void ContextProviderInProcess::OnMemoryAllocationChanged(
bool nonzero_allocation) {
+ DCHECK(context_thread_checker_.CalledOnValidThread());
if (gr_context_)
gr_context_->SetMemoryLimit(nonzero_allocation);
}
diff --git a/webkit/common/gpu/context_provider_in_process.h b/webkit/common/gpu/context_provider_in_process.h
index b87fc91..b427abe 100644
--- a/webkit/common/gpu/context_provider_in_process.h
+++ b/webkit/common/gpu/context_provider_in_process.h
@@ -8,6 +8,7 @@
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
+#include "base/threading/thread_checker.h"
#include "cc/output/context_provider.h"
#include "webkit/common/gpu/webkit_gpu_export.h"
@@ -35,6 +36,8 @@ class WEBKIT_GPU_EXPORT ContextProviderInProcess
virtual class GrContext* GrContext() OVERRIDE;
virtual void VerifyContexts() OVERRIDE;
virtual bool DestroyedOnMainThread() OVERRIDE;
+ virtual void SetLostContextCallback(
+ const LostContextCallback& lost_context_callback) OVERRIDE;
protected:
ContextProviderInProcess();
@@ -42,14 +45,18 @@ class WEBKIT_GPU_EXPORT ContextProviderInProcess
bool InitializeOnMainThread();
- void OnLostContextInternal();
- virtual void OnLostContext() {}
- virtual void OnMemoryAllocationChanged(bool nonzero_allocation);
+ void OnLostContext();
+ void OnMemoryAllocationChanged(bool nonzero_allocation);
private:
+ base::ThreadChecker main_thread_checker_;
+ base::ThreadChecker context_thread_checker_;
+
scoped_ptr<WebKit::WebGraphicsContext3D> context3d_;
scoped_ptr<webkit::gpu::GrContextForWebGraphicsContext3D> gr_context_;
+ LostContextCallback lost_context_callback_;
+
base::Lock destroyed_lock_;
bool destroyed_;