diff options
author | piman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-13 05:05:37 +0000 |
---|---|---|
committer | piman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-13 05:05:37 +0000 |
commit | 40034cfd142fa1a9801434d545ade1c85146ab7c (patch) | |
tree | 4a4cb8c60bd819a80b532e8b5dddfde679710a81 | |
parent | 8d8e2f67a179aa07c8e9b8206c81a31cb46028f0 (diff) | |
download | chromium_src-40034cfd142fa1a9801434d545ade1c85146ab7c.zip chromium_src-40034cfd142fa1a9801434d545ade1c85146ab7c.tar.gz chromium_src-40034cfd142fa1a9801434d545ade1c85146ab7c.tar.bz2 |
Aura: sanitize --test-compositor to act like a proper ContextFactory
Previous code would initialize GL in the browser_tests browser process even
though we'll either use test (noop) contexts, or GPU process ones. This causes
issues with some drivers as we try to fork after the GL library is loaded.
BUG=180753
Review URL: https://chromiumcodereview.appspot.com/12575003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@187785 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | content/browser/renderer_host/image_transport_factory.cc | 73 | ||||
-rw-r--r-- | ui/compositor/compositor.cc | 194 | ||||
-rw-r--r-- | ui/compositor/compositor.h | 38 |
3 files changed, 183 insertions, 122 deletions
diff --git a/content/browser/renderer_host/image_transport_factory.cc b/content/browser/renderer_host/image_transport_factory.cc index e46f68a..01aa4db 100644 --- a/content/browser/renderer_host/image_transport_factory.cc +++ b/content/browser/renderer_host/image_transport_factory.cc @@ -50,16 +50,15 @@ namespace { ImageTransportFactory* g_factory; -class DefaultTransportFactory - : public ui::DefaultContextFactory, - public ImageTransportFactory { +// An ImageTransportFactory that disables transport. +class NoTransportFactory : public ImageTransportFactory { public: - DefaultTransportFactory() { - ui::DefaultContextFactory::Initialize(); + explicit NoTransportFactory(ui::ContextFactory* context_factory) + : context_factory_(context_factory) { } virtual ui::ContextFactory* AsContextFactory() OVERRIDE { - return this; + return context_factory_.get(); } virtual gfx::GLSurfaceHandle CreateSharedSurfaceHandle() OVERRIDE { @@ -103,7 +102,8 @@ class DefaultTransportFactory } private: - DISALLOW_COPY_AND_ASSIGN(DefaultTransportFactory); + scoped_ptr<ui::ContextFactory> context_factory_; + DISALLOW_COPY_AND_ASSIGN(NoTransportFactory); }; class OwnedTexture : public ui::Texture, ImageTransportFactoryObserver { @@ -678,16 +678,36 @@ void CompositorSwapClient::OnLostContext() { // Note: previous line destroyed this. Don't access members from now on. } -WebKit::WebGraphicsContext3D* CreateTestContext() { - ui::TestWebGraphicsContext3D* test_context = - new ui::TestWebGraphicsContext3D(); - test_context->Initialize(); - return test_context; -} +class FailingContextProvider : public cc::ContextProvider { + public: + FailingContextProvider() {} + + virtual bool InitializeOnMainThread() OVERRIDE { return false; } + + virtual bool BindToCurrentThread() OVERRIDE { + NOTREACHED(); + return false; + } + + virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE { return NULL; } + virtual class GrContext* GrContext() OVERRIDE { return NULL; } + virtual void VerifyContexts() OVERRIDE {} + virtual bool DestroyedOnMainThread() OVERRIDE { return false; } + + protected: + virtual ~FailingContextProvider() {} + DISALLOW_COPY_AND_ASSIGN(FailingContextProvider); +}; -class SoftwareTransportFactory : public DefaultTransportFactory { +class SoftwareContextFactory : public ui::ContextFactory { public: - cc::OutputSurface* CreateOutputSurface(ui::Compositor* compositor) { + SoftwareContextFactory() {} + virtual ~SoftwareContextFactory() {} + virtual WebKit::WebGraphicsContext3D* CreateOffscreenContext() OVERRIDE { + return NULL; + } + virtual cc::OutputSurface* CreateOutputSurface( + ui::Compositor* compositor) OVERRIDE { #if defined(OS_WIN) scoped_ptr<SoftwareOutputDeviceWin> software_device( new SoftwareOutputDeviceWin(compositor)); @@ -703,6 +723,25 @@ class SoftwareTransportFactory : public DefaultTransportFactory { return NULL; #endif } + virtual void RemoveCompositor(ui::Compositor* compositor) OVERRIDE {} + + virtual scoped_refptr<cc::ContextProvider> + OffscreenContextProviderForMainThread() OVERRIDE { + if (!context_provider_) + context_provider_ = new FailingContextProvider(); + return context_provider_; + } + + virtual scoped_refptr<cc::ContextProvider> + OffscreenContextProviderForCompositorThread() OVERRIDE { + if (!context_provider_) + context_provider_ = new FailingContextProvider(); + return context_provider_; + } + + private: + scoped_refptr<FailingContextProvider> context_provider_; + DISALLOW_COPY_AND_ASSIGN(SoftwareContextFactory); }; } // anonymous namespace @@ -714,9 +753,9 @@ void ImageTransportFactory::Initialize() { ui::SetupTestCompositor(); } if (ui::IsTestCompositorEnabled()) { - g_factory = new DefaultTransportFactory; + g_factory = new NoTransportFactory(new ui::TestContextFactory); } else if (command_line->HasSwitch(switches::kUIEnableSoftwareCompositing)) { - g_factory = new SoftwareTransportFactory; + g_factory = new NoTransportFactory(new SoftwareContextFactory); } else { g_factory = new GpuProcessTransportFactory; } diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc index d4f1708..4ecabdc 100644 --- a/ui/compositor/compositor.cc +++ b/ui/compositor/compositor.cc @@ -51,6 +51,7 @@ base::Thread* g_compositor_thread = NULL; bool g_test_compositor_enabled = false; +ui::ContextFactory* g_implicit_factory = NULL; ui::ContextFactory* g_context_factory = NULL; const int kCompositorLockTimeoutMs = 67; @@ -73,34 +74,30 @@ class PendingSwap { DISALLOW_COPY_AND_ASSIGN(PendingSwap); }; -class NullContextProvider : public cc::ContextProvider { - public: - virtual bool InitializeOnMainThread() OVERRIDE { return false; } - virtual bool BindToCurrentThread() OVERRIDE { return false; } - virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE { return NULL; } - virtual class GrContext* GrContext() OVERRIDE { return NULL; } - virtual void VerifyContexts() OVERRIDE {} - virtual bool DestroyedOnMainThread() OVERRIDE { return false; } - - protected: - virtual ~NullContextProvider() {} -}; - -struct MainThreadNullContextProvider { - scoped_refptr<NullContextProvider> provider; - - static MainThreadNullContextProvider* GetInstance() { - return Singleton<MainThreadNullContextProvider>::get(); +void SetupImplicitFactory() { + // We leak the implicit factory so that we don't race with the tear down of + // the gl_bindings. + DCHECK(!g_context_factory); + DCHECK(!g_implicit_factory); + if (g_test_compositor_enabled) { + g_implicit_factory = new ui::TestContextFactory; + } else { + DVLOG(1) << "Using DefaultContextFactory"; + scoped_ptr<ui::DefaultContextFactory> instance( + new ui::DefaultContextFactory()); + if (instance->Initialize()) + g_implicit_factory = instance.release(); } -}; - -struct CompositorThreadNullContextProvider { - scoped_refptr<NullContextProvider> provider; + g_context_factory = g_implicit_factory; +} - static CompositorThreadNullContextProvider* GetInstance() { - return Singleton<CompositorThreadNullContextProvider>::get(); - } -}; +void ResetImplicitFactory() { + if (!g_implicit_factory || g_context_factory != g_implicit_factory) + return; + delete g_implicit_factory; + g_implicit_factory = NULL; + g_context_factory = NULL; +} } // namespace @@ -108,15 +105,8 @@ namespace ui { // static ContextFactory* ContextFactory::GetInstance() { - // We leak the shared resources so that we don't race with - // the tear down of the gl_bindings. - if (!g_context_factory) { - DVLOG(1) << "Using DefaultSharedResource"; - scoped_ptr<DefaultContextFactory> instance( - new DefaultContextFactory()); - if (instance->Initialize()) - g_context_factory = instance.release(); - } + if (!g_context_factory) + SetupImplicitFactory(); return g_context_factory; } @@ -125,39 +115,9 @@ void ContextFactory::SetInstance(ContextFactory* instance) { g_context_factory = instance; } -DefaultContextFactory::DefaultContextFactory() { -} - -DefaultContextFactory::~DefaultContextFactory() { -} - -bool DefaultContextFactory::Initialize() { - // The following line of code exists soley to disable IO restrictions - // on this thread long enough to perform the GL bindings. - // TODO(wjmaclean) Remove this when GL initialisation cleaned up. - base::ThreadRestrictions::ScopedAllowIO allow_io; - if (!gfx::GLSurface::InitializeOneOff() || - gfx::GetGLImplementation() == gfx::kGLImplementationNone) { - LOG(ERROR) << "Could not load the GL bindings"; - return false; - } - return true; -} - -cc::OutputSurface* DefaultContextFactory::CreateOutputSurface( - Compositor* compositor) { - return new cc::OutputSurface( - make_scoped_ptr(CreateContextCommon(compositor, false))); -} - -WebKit::WebGraphicsContext3D* DefaultContextFactory::CreateOffscreenContext() { - return CreateContextCommon(NULL, true); -} - -class DefaultContextFactory::DefaultContextProvider - : public cc::ContextProvider { +class ContextProviderFromContextFactory : public cc::ContextProvider { public: - DefaultContextProvider(ContextFactory* factory) + explicit ContextProviderFromContextFactory(ContextFactory* factory) : factory_(factory), destroyed_(false) {} @@ -195,7 +155,7 @@ class DefaultContextFactory::DefaultContextProvider } protected: - virtual ~DefaultContextProvider() {} + virtual ~ContextProviderFromContextFactory() {} private: ContextFactory* factory_; @@ -205,11 +165,37 @@ class DefaultContextFactory::DefaultContextProvider scoped_ptr<webkit::gpu::GrContextForWebGraphicsContext3D> gr_context_; }; +DefaultContextFactory::DefaultContextFactory() { +} + +DefaultContextFactory::~DefaultContextFactory() { +} + +bool DefaultContextFactory::Initialize() { + if (!gfx::GLSurface::InitializeOneOff() || + gfx::GetGLImplementation() == gfx::kGLImplementationNone) { + LOG(ERROR) << "Could not load the GL bindings"; + return false; + } + return true; +} + +cc::OutputSurface* DefaultContextFactory::CreateOutputSurface( + Compositor* compositor) { + return new cc::OutputSurface( + make_scoped_ptr(CreateContextCommon(compositor, false))); +} + +WebKit::WebGraphicsContext3D* DefaultContextFactory::CreateOffscreenContext() { + return CreateContextCommon(NULL, true); +} + scoped_refptr<cc::ContextProvider> DefaultContextFactory::OffscreenContextProviderForMainThread() { if (!offscreen_contexts_main_thread_ || !offscreen_contexts_main_thread_->DestroyedOnMainThread()) { - offscreen_contexts_main_thread_ = new DefaultContextProvider(this); + offscreen_contexts_main_thread_ = + new ContextProviderFromContextFactory(this); } return offscreen_contexts_main_thread_; } @@ -218,7 +204,8 @@ scoped_refptr<cc::ContextProvider> DefaultContextFactory::OffscreenContextProviderForCompositorThread() { if (!offscreen_contexts_compositor_thread_ || !offscreen_contexts_compositor_thread_->DestroyedOnMainThread()) { - offscreen_contexts_compositor_thread_ = new DefaultContextProvider(this); + offscreen_contexts_compositor_thread_ = + new ContextProviderFromContextFactory(this); } return offscreen_contexts_compositor_thread_; } @@ -240,7 +227,7 @@ WebKit::WebGraphicsContext3D* DefaultContextFactory::CreateContextCommon( webkit::gpu::WebGraphicsContext3DInProcessImpl::CreateForWebView( attrs, false) : webkit::gpu::WebGraphicsContext3DInProcessImpl::CreateForWindow( - attrs, compositor->widget(), share_group_.get()); + attrs, compositor->widget(), NULL); if (!context) return NULL; @@ -255,6 +242,40 @@ WebKit::WebGraphicsContext3D* DefaultContextFactory::CreateContextCommon( return context; } +TestContextFactory::TestContextFactory() { + offscreen_contexts_main_thread_ = + new ContextProviderFromContextFactory(this); + offscreen_contexts_compositor_thread_ = + new ContextProviderFromContextFactory(this); +} + +TestContextFactory::~TestContextFactory() { +} + +cc::OutputSurface* TestContextFactory::CreateOutputSurface( + Compositor* compositor) { + return new cc::OutputSurface(make_scoped_ptr(CreateOffscreenContext())); +} + +WebKit::WebGraphicsContext3D* TestContextFactory::CreateOffscreenContext() { + ui::TestWebGraphicsContext3D* context = new ui::TestWebGraphicsContext3D; + context->Initialize(); + return context; +} + +scoped_refptr<cc::ContextProvider> +TestContextFactory::OffscreenContextProviderForMainThread() { + return offscreen_contexts_main_thread_; +} + +scoped_refptr<cc::ContextProvider> +TestContextFactory::OffscreenContextProviderForCompositorThread() { + return offscreen_contexts_compositor_thread_; +} + +void TestContextFactory::RemoveCompositor(Compositor* compositor) { +} + Texture::Texture(bool flipped, const gfx::Size& size, float device_scale_factor) : size_(size), flipped_(flipped), @@ -406,8 +427,7 @@ Compositor::~Compositor() { // down any contexts that the |host_| may rely upon. host_.reset(); - if (!g_test_compositor_enabled) - ContextFactory::GetInstance()->RemoveCompositor(this); + ContextFactory::GetInstance()->RemoveCompositor(this); } void Compositor::Initialize(bool use_thread) { @@ -573,16 +593,8 @@ void Compositor::applyScrollAndScale(gfx::Vector2d scrollDelta, } scoped_ptr<cc::OutputSurface> Compositor::createOutputSurface() { - if (g_test_compositor_enabled) { - scoped_ptr<ui::TestWebGraphicsContext3D> context3d( - new ui::TestWebGraphicsContext3D); - context3d->Initialize(); - return make_scoped_ptr(new cc::OutputSurface( - context3d.PassAs<WebKit::WebGraphicsContext3D>())); - } else { - return make_scoped_ptr( - ContextFactory::GetInstance()->CreateOutputSurface(this)); - } + return make_scoped_ptr( + ContextFactory::GetInstance()->CreateOutputSurface(this)); } void Compositor::didRecreateOutputSurface(bool success) { @@ -621,25 +633,11 @@ void Compositor::scheduleComposite() { scoped_refptr<cc::ContextProvider> Compositor::OffscreenContextProviderForMainThread() { - if (g_test_compositor_enabled) { - if (!MainThreadNullContextProvider::GetInstance()->provider) { - MainThreadNullContextProvider::GetInstance()->provider = - new NullContextProvider; - } - return MainThreadNullContextProvider::GetInstance()->provider; - } return ContextFactory::GetInstance()->OffscreenContextProviderForMainThread(); } scoped_refptr<cc::ContextProvider> Compositor::OffscreenContextProviderForCompositorThread() { - if (g_test_compositor_enabled) { - if (!CompositorThreadNullContextProvider::GetInstance()->provider) { - CompositorThreadNullContextProvider::GetInstance()->provider = - new NullContextProvider; - } - return CompositorThreadNullContextProvider::GetInstance()->provider; - } return ContextFactory::GetInstance()-> OffscreenContextProviderForCompositorThread(); } @@ -689,9 +687,11 @@ COMPOSITOR_EXPORT void SetupTestCompositor() { if (base::chromeos::IsRunningOnChromeOS()) g_test_compositor_enabled = false; #endif + ResetImplicitFactory(); } COMPOSITOR_EXPORT void DisableTestCompositor() { + ResetImplicitFactory(); g_test_compositor_enabled = false; } diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h index 1f263e2..b5b1f0c 100644 --- a/ui/compositor/compositor.h +++ b/ui/compositor/compositor.h @@ -43,6 +43,7 @@ namespace ui { class Compositor; class CompositorObserver; +class ContextProviderFromContextFactory; class Layer; class PostedSwapQueue; @@ -97,23 +98,44 @@ class COMPOSITOR_EXPORT DefaultContextFactory : public ContextFactory { bool Initialize(); - void set_share_group(gfx::GLShareGroup* share_group) { - share_group_ = share_group; - } - private: WebKit::WebGraphicsContext3D* CreateContextCommon( Compositor* compositor, bool offscreen); - scoped_refptr<gfx::GLShareGroup> share_group_; - class DefaultContextProvider; - scoped_refptr<DefaultContextProvider> offscreen_contexts_main_thread_; - scoped_refptr<DefaultContextProvider> offscreen_contexts_compositor_thread_; + scoped_refptr<ContextProviderFromContextFactory> + offscreen_contexts_main_thread_; + scoped_refptr<ContextProviderFromContextFactory> + offscreen_contexts_compositor_thread_; DISALLOW_COPY_AND_ASSIGN(DefaultContextFactory); }; +// The factory that creates test contexts. +class COMPOSITOR_EXPORT TestContextFactory : public ContextFactory { + public: + TestContextFactory(); + virtual ~TestContextFactory(); + + // ContextFactory implementation + virtual cc::OutputSurface* CreateOutputSurface( + Compositor* compositor) OVERRIDE; + virtual WebKit::WebGraphicsContext3D* CreateOffscreenContext() OVERRIDE; + virtual scoped_refptr<cc::ContextProvider> + OffscreenContextProviderForMainThread() OVERRIDE; + virtual scoped_refptr<cc::ContextProvider> + OffscreenContextProviderForCompositorThread() OVERRIDE; + virtual void RemoveCompositor(Compositor* compositor) OVERRIDE; + + private: + scoped_refptr<ContextProviderFromContextFactory> + offscreen_contexts_main_thread_; + scoped_refptr<ContextProviderFromContextFactory> + offscreen_contexts_compositor_thread_; + + DISALLOW_COPY_AND_ASSIGN(TestContextFactory); +}; + // Texture provide an abstraction over the external texture that can be passed // to a layer. class COMPOSITOR_EXPORT Texture : public base::RefCounted<Texture> { |