diff options
-rw-r--r-- | cc/output/context_provider.h | 9 | ||||
-rw-r--r-- | cc/test/fake_context_provider.cc | 42 | ||||
-rw-r--r-- | cc/test/fake_context_provider.h | 19 | ||||
-rw-r--r-- | content/browser/aura/gpu_process_transport_factory.cc | 80 | ||||
-rw-r--r-- | content/browser/aura/gpu_process_transport_factory.h | 43 | ||||
-rw-r--r-- | content/common/gpu/client/context_provider_command_buffer.cc | 49 | ||||
-rw-r--r-- | content/common/gpu/client/context_provider_command_buffer.h | 24 | ||||
-rw-r--r-- | content/renderer/render_thread_impl.cc | 30 | ||||
-rw-r--r-- | content/renderer/render_thread_impl.h | 6 | ||||
-rw-r--r-- | ui/compositor/context_provider_from_context_factory.cc | 5 | ||||
-rw-r--r-- | ui/compositor/context_provider_from_context_factory.h | 1 | ||||
-rw-r--r-- | webkit/common/gpu/context_provider_in_process.cc | 35 | ||||
-rw-r--r-- | webkit/common/gpu/context_provider_in_process.h | 13 |
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_; |