diff options
author | bajones@chromium.org <bajones@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-25 18:19:36 +0000 |
---|---|---|
committer | bajones@chromium.org <bajones@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-25 18:19:36 +0000 |
commit | 4f8fd780d9f89de79b4db6bdb2b555a4fabcc255 (patch) | |
tree | 5a4ad338ec1dea1c747238222f54f98904814bf2 | |
parent | b618ffe8cc03fd713a5ca3ad623c22d76fec41d1 (diff) | |
download | chromium_src-4f8fd780d9f89de79b4db6bdb2b555a4fabcc255.zip chromium_src-4f8fd780d9f89de79b4db6bdb2b555a4fabcc255.tar.gz chromium_src-4f8fd780d9f89de79b4db6bdb2b555a4fabcc255.tar.bz2 |
Plumbing explicit share groups through context creation
Requires corresponding Blink changes, which is why the new interfaces are hidden
behind #ifdefs.
BUG=127940
R=kbr@chromium.org, piman@chromium.org, sievers@chromium.org
Review URL: https://codereview.chromium.org/101223005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@253204 0039d316-1c4b-4281-b951-d872f2087c98
11 files changed, 165 insertions, 72 deletions
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc index 0aff1ba..bc74cd3 100644 --- a/content/browser/compositor/gpu_process_transport_factory.cc +++ b/content/browser/compositor/gpu_process_transport_factory.cc @@ -444,7 +444,8 @@ GpuProcessTransportFactory::CreateContextCommon(int surface_id) { gpu_channel_host.get(), attrs, false, - WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits())); + WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(), + NULL)); return context.Pass(); } diff --git a/content/browser/gpu/gpu_ipc_browsertests.cc b/content/browser/gpu/gpu_ipc_browsertests.cc index d1ebfff..e417375 100644 --- a/content/browser/gpu/gpu_ipc_browsertests.cc +++ b/content/browser/gpu/gpu_ipc_browsertests.cc @@ -42,7 +42,8 @@ class ContextTestBase : public content::ContentBrowserTest { gpu_channel_host.get(), blink::WebGraphicsContext3D::Attributes(), GURL(), - WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits())); + WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(), + NULL)); CHECK(context_.get()); context_->makeContextCurrent(); context_support_ = context_->GetContextSupport(); @@ -129,7 +130,8 @@ class BrowserGpuChannelHostFactoryTest : public ContextTestBase { GetGpuChannel(), blink::WebGraphicsContext3D::Attributes(), GURL(), - WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits())); + WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(), + NULL)); } }; diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index 2cb2e65..72fe725 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc @@ -403,7 +403,8 @@ CreateGpuProcessViewContext( gpu_channel_host.get(), attributes, false, - limits)); + limits, + NULL)); } scoped_ptr<cc::OutputSurface> CompositorImpl::CreateOutputSurface( diff --git a/content/browser/renderer_host/image_transport_factory_android.cc b/content/browser/renderer_host/image_transport_factory_android.cc index dd4ec6e..7080ddc 100644 --- a/content/browser/renderer_host/image_transport_factory_android.cc +++ b/content/browser/renderer_host/image_transport_factory_android.cc @@ -88,7 +88,8 @@ CmdBufferImageTransportFactory::CmdBufferImageTransportFactory() { gpu_channel_host.get(), attrs, false, - limits)); + limits, + NULL)); context_->setContextLostCallback(context_lost_listener_.get()); if (context_->makeContextCurrent()) context_->pushGroupMarkerEXT( diff --git a/content/common/gpu/client/context_provider_command_buffer_browsertest.cc b/content/common/gpu/client/context_provider_command_buffer_browsertest.cc index b51db15..eb552e5 100644 --- a/content/common/gpu/client/context_provider_command_buffer_browsertest.cc +++ b/content/common/gpu/client/context_provider_command_buffer_browsertest.cc @@ -38,7 +38,8 @@ class ContextProviderCommandBufferBrowserTest : public ContentBrowserTest { gpu_channel_host.get(), blink::WebGraphicsContext3D::Attributes(), GURL("chrome://gpu/ContextProviderCommandBufferTest"), - WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits())); + WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(), + NULL)); return context.Pass(); } }; diff --git a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc index 8bd6618..145535e 100644 --- a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc +++ b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc @@ -22,7 +22,6 @@ #include "base/message_loop/message_loop.h" #include "base/metrics/field_trial.h" #include "base/metrics/histogram.h" -#include "base/synchronization/lock.h" #include "content/common/gpu/client/gpu_channel_host.h" #include "content/public/common/content_constants.h" #include "content/public/common/content_switches.h" @@ -43,13 +42,29 @@ namespace content { namespace { static base::LazyInstance<base::Lock>::Leaky - g_all_shared_contexts_lock = LAZY_INSTANCE_INITIALIZER; + g_default_share_groups_lock = LAZY_INSTANCE_INITIALIZER; -typedef std::multimap<GpuChannelHost*, WebGraphicsContext3DCommandBufferImpl*> - ContextMap; -static base::LazyInstance<ContextMap> g_all_shared_contexts = +typedef std::map<GpuChannelHost*, + scoped_refptr<WebGraphicsContext3DCommandBufferImpl::ShareGroup> > + ShareGroupMap; +static base::LazyInstance<ShareGroupMap> g_default_share_groups = LAZY_INSTANCE_INITIALIZER; +scoped_refptr<WebGraphicsContext3DCommandBufferImpl::ShareGroup> + GetDefaultShareGroupForHost(GpuChannelHost* host) { + base::AutoLock lock(g_default_share_groups_lock.Get()); + + ShareGroupMap& share_groups = g_default_share_groups.Get(); + ShareGroupMap::iterator it = share_groups.find(host); + if (it == share_groups.end()) { + scoped_refptr<WebGraphicsContext3DCommandBufferImpl::ShareGroup> group = + new WebGraphicsContext3DCommandBufferImpl::ShareGroup(); + share_groups[host] = group; + return group; + } + return it->second; +} + uint32_t GenFlushID() { static base::subtle::Atomic32 flush_id = 0; @@ -202,13 +217,21 @@ WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits::SharedMemoryLimits() max_transfer_buffer_size(kDefaultMaxTransferBufferSize), mapped_memory_reclaim_limit(gpu::gles2::GLES2Implementation::kNoLimit) {} +WebGraphicsContext3DCommandBufferImpl::ShareGroup::ShareGroup() { +} + +WebGraphicsContext3DCommandBufferImpl::ShareGroup::~ShareGroup() { + DCHECK(contexts_.empty()); +} + WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl( int surface_id, const GURL& active_url, GpuChannelHost* host, const Attributes& attributes, bool bind_generates_resources, - const SharedMemoryLimits& limits) + const SharedMemoryLimits& limits, + WebGraphicsContext3DCommandBufferImpl* share_context) : initialize_failed_(false), visible_(false), host_(host), @@ -226,6 +249,15 @@ WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl( bind_generates_resources_(bind_generates_resources), mem_limits_(limits), flush_id_(0) { + if (share_context) { + DCHECK(!attributes_.shareResources); + share_group_ = share_context->share_group_; + } else { + share_group_ = attributes_.shareResources + ? GetDefaultShareGroupForHost(host) + : scoped_refptr<WebGraphicsContext3DCommandBufferImpl::ShareGroup>( + new ShareGroup()); + } } WebGraphicsContext3DCommandBufferImpl:: @@ -295,19 +327,14 @@ bool WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL() { } bool WebGraphicsContext3DCommandBufferImpl::InitializeCommandBuffer( - bool onscreen) { + bool onscreen, WebGraphicsContext3DCommandBufferImpl* share_context) { if (!host_.get()) return false; - // We need to lock g_all_shared_contexts to ensure that the context we picked - // for our share group isn't deleted. - // (There's also a lock in our destructor.) - base::AutoLock lock(g_all_shared_contexts_lock.Get()); - CommandBufferProxyImpl* share_group = NULL; - if (attributes_.shareResources) { - ContextMap& all_contexts = g_all_shared_contexts.Get(); - ContextMap::const_iterator it = all_contexts.find(host_.get()); - if (it != all_contexts.end()) - share_group = it->second->command_buffer_.get(); + + CommandBufferProxyImpl* share_group_command_buffer = NULL; + + if (share_context) { + share_group_command_buffer = share_context->command_buffer_.get(); } std::vector<int32> attribs; @@ -329,14 +356,14 @@ bool WebGraphicsContext3DCommandBufferImpl::InitializeCommandBuffer( if (onscreen) { command_buffer_.reset(host_->CreateViewCommandBuffer( surface_id_, - share_group, + share_group_command_buffer, attribs, active_url_, gpu_preference_)); } else { command_buffer_.reset(host_->CreateOffscreenCommandBuffer( gfx::Size(1, 1), - share_group, + share_group_command_buffer, attribs, active_url_, gpu_preference_)); @@ -349,14 +376,27 @@ bool WebGraphicsContext3DCommandBufferImpl::InitializeCommandBuffer( return command_buffer_->Initialize(); } -bool WebGraphicsContext3DCommandBufferImpl::CreateContext( - bool onscreen) { +bool WebGraphicsContext3DCommandBufferImpl::CreateContext(bool onscreen) { // Ensure the gles2 library is initialized first in a thread safe way. g_gles2_initializer.Get(); - if (!command_buffer_ && - !InitializeCommandBuffer(onscreen)) { - return false; + scoped_refptr<gpu::gles2::ShareGroup> gles2_share_group; + + scoped_ptr<base::AutoLock> share_group_lock; + bool add_to_share_group = false; + if (!command_buffer_) { + WebGraphicsContext3DCommandBufferImpl* share_context = NULL; + + share_group_lock.reset(new base::AutoLock(share_group_->lock())); + share_context = share_group_->GetAnyContextLocked(); + + if (!InitializeCommandBuffer(onscreen, share_context)) + return false; + + if (share_context) + gles2_share_group = share_context->GetImplementation()->share_group(); + + add_to_share_group = true; } // Create the GLES2 helper, which writes the command buffer protocol. @@ -372,19 +412,6 @@ bool WebGraphicsContext3DCommandBufferImpl::CreateContext( transfer_buffer_ .reset(new gpu::TransferBuffer(gles2_helper_.get())); DCHECK(host_.get()); - scoped_ptr<base::AutoLock> lock; - scoped_refptr<gpu::gles2::ShareGroup> share_group; - if (attributes_.shareResources) { - // Make sure two clients don't try to create a new ShareGroup - // simultaneously. - lock.reset(new base::AutoLock(g_all_shared_contexts_lock.Get())); - ContextMap& all_contexts = g_all_shared_contexts.Get(); - ContextMap::const_iterator it = all_contexts.find(host_.get()); - if (it != all_contexts.end()) { - share_group = it->second->GetImplementation()->share_group(); - DCHECK(share_group); - } - } const CommandLine& command_line = *CommandLine::ForCurrentProcess(); bool free_command_buffer_when_invisible = @@ -393,19 +420,13 @@ bool WebGraphicsContext3DCommandBufferImpl::CreateContext( // Create the object exposing the OpenGL API. real_gl_.reset(new gpu::gles2::GLES2Implementation( gles2_helper_.get(), - share_group, + gles2_share_group, transfer_buffer_.get(), bind_generates_resources_, free_command_buffer_when_invisible, command_buffer_.get())); gl_ = real_gl_.get(); - if (attributes_.shareResources) { - // Don't add ourselves to the list before others can get to our ShareGroup. - g_all_shared_contexts.Get().insert(std::make_pair(host_.get(), this)); - lock.reset(); - } - if (!real_gl_->Initialize( mem_limits_.start_transfer_buffer_size, mem_limits_.min_transfer_buffer_size, @@ -414,6 +435,9 @@ bool WebGraphicsContext3DCommandBufferImpl::CreateContext( return false; } + if (add_to_share_group) + share_group_->AddContextLocked(this); + if (CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableGpuClientTracing)) { trace_gl_.reset(new gpu::gles2::GLES2TraceImplementation(gl_)); @@ -440,17 +464,7 @@ uint32_t WebGraphicsContext3DCommandBufferImpl::lastFlushID() { DELEGATE_TO_GL_R(insertSyncPoint, InsertSyncPointCHROMIUM, unsigned int) void WebGraphicsContext3DCommandBufferImpl::Destroy() { - if (host_.get()) { - base::AutoLock lock(g_all_shared_contexts_lock.Get()); - ContextMap& all_contexts = g_all_shared_contexts.Get(); - ContextMap::iterator it = std::find( - all_contexts.begin(), - all_contexts.end(), - std::pair<GpuChannelHost* const, - WebGraphicsContext3DCommandBufferImpl*>(host_.get(), this)); - if (it != all_contexts.end()) - all_contexts.erase(it); - } + share_group_->RemoveContext(this); if (gl_) { // First flush the context to ensure that any pending frees of resources @@ -1168,15 +1182,21 @@ WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext( GpuChannelHost* host, const WebGraphicsContext3D::Attributes& attributes, const GURL& active_url, - const SharedMemoryLimits& limits) { + const SharedMemoryLimits& limits, + WebGraphicsContext3DCommandBufferImpl* share_context) { if (!host) return NULL; + + if (share_context && share_context->IsCommandBufferContextLost()) + return NULL; + return new WebGraphicsContext3DCommandBufferImpl(0, active_url, host, attributes, false, - limits); + limits, + share_context); } DELEGATE_TO_GL_5(texImageIOSurface2DCHROMIUM, TexImageIOSurface2DCHROMIUM, @@ -1349,10 +1369,12 @@ void WebGraphicsContext3DCommandBufferImpl::OnGpuChannelLost() { context_lost_callback_->onContextLost(); } + share_group_->RemoveAllContexts(); + DCHECK(host_.get()); { - base::AutoLock lock(g_all_shared_contexts_lock.Get()); - g_all_shared_contexts.Get().erase(host_.get()); + base::AutoLock lock(g_default_share_groups_lock.Get()); + g_default_share_groups.Get().erase(host_.get()); } } diff --git a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h index bac7499..2ff411b 100644 --- a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h +++ b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h @@ -11,6 +11,7 @@ #include "base/callback.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" +#include "base/synchronization/lock.h" #include "content/common/content_export.h" #include "content/common/gpu/client/command_buffer_proxy_impl.h" #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" @@ -73,13 +74,58 @@ class WebGraphicsContext3DCommandBufferImpl size_t mapped_memory_reclaim_limit; }; + class ShareGroup : public base::RefCountedThreadSafe<ShareGroup> { + public: + ShareGroup(); + + WebGraphicsContext3DCommandBufferImpl* GetAnyContextLocked() { + // In order to ensure that the context returned is not removed while + // in use, the share group's lock should be aquired before calling this + // function. + lock_.AssertAcquired(); + if (contexts_.empty()) + return NULL; + return contexts_.front(); + } + + void AddContextLocked(WebGraphicsContext3DCommandBufferImpl* context) { + lock_.AssertAcquired(); + contexts_.push_back(context); + } + + void RemoveContext(WebGraphicsContext3DCommandBufferImpl* context) { + base::AutoLock auto_lock(lock_); + contexts_.erase(std::remove(contexts_.begin(), contexts_.end(), context), + contexts_.end()); + } + + void RemoveAllContexts() { + base::AutoLock auto_lock(lock_); + contexts_.clear(); + } + + base::Lock& lock() { + return lock_; + } + + private: + friend class base::RefCountedThreadSafe<ShareGroup>; + virtual ~ShareGroup(); + + std::vector<WebGraphicsContext3DCommandBufferImpl*> contexts_; + base::Lock lock_; + + DISALLOW_COPY_AND_ASSIGN(ShareGroup); + }; + WebGraphicsContext3DCommandBufferImpl( int surface_id, const GURL& active_url, GpuChannelHost* host, const Attributes& attributes, bool bind_generates_resources, - const SharedMemoryLimits& limits); + const SharedMemoryLimits& limits, + WebGraphicsContext3DCommandBufferImpl* share_context); virtual ~WebGraphicsContext3DCommandBufferImpl(); @@ -104,7 +150,8 @@ class WebGraphicsContext3DCommandBufferImpl GpuChannelHost* host, const WebGraphicsContext3D::Attributes& attributes, const GURL& active_url, - const SharedMemoryLimits& limits); + const SharedMemoryLimits& limits, + WebGraphicsContext3DCommandBufferImpl* share_context); size_t GetMappedMemoryLimit() { return mem_limits_.mapped_memory_reclaim_limit; @@ -663,7 +710,8 @@ class WebGraphicsContext3DCommandBufferImpl // thread). bool MaybeInitializeGL(); - bool InitializeCommandBuffer(bool onscreen); + bool InitializeCommandBuffer(bool onscreen, + WebGraphicsContext3DCommandBufferImpl* share_context); void Destroy(); @@ -722,6 +770,7 @@ class WebGraphicsContext3DCommandBufferImpl SharedMemoryLimits mem_limits_; uint32_t flush_id_; + scoped_refptr<ShareGroup> share_group_; }; } // namespace content diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 753244f..c266cab 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc @@ -910,7 +910,8 @@ RenderThreadImpl::GetGpuFactories() { gpu_channel_host.get(), blink::WebGraphicsContext3D::Attributes(), GURL("chrome://gpu/RenderThreadImpl::GetGpuVDAContext3D"), - WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits())), + WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(), + NULL)), "GPU-VideoAccelerator-Offscreen"); if (gpu_va_context_provider_) { media_loop_proxy->PostTask( @@ -944,7 +945,8 @@ RenderThreadImpl::CreateOffscreenContext3d() { gpu_channel_host.get(), attributes, GURL("chrome://gpu/RenderThreadImpl::CreateOffscreenContext3d"), - WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits())); + WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(), + NULL)); } scoped_refptr<cc::ContextProvider> diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index fc88cbac..84a2b3b 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc @@ -2780,7 +2780,8 @@ RenderWidget::CreateGraphicsContext3D( gpu_channel_host.get(), attributes, false /* bind generates resources */, - limits)); + limits, + NULL)); return context.Pass(); } diff --git a/content/renderer/renderer_webkitplatformsupport_impl.cc b/content/renderer/renderer_webkitplatformsupport_impl.cc index 601fd5c..18d0bf2 100644 --- a/content/renderer/renderer_webkitplatformsupport_impl.cc +++ b/content/renderer/renderer_webkitplatformsupport_impl.cc @@ -940,9 +940,16 @@ bool RendererWebKitPlatformSupportImpl::processMemorySizesInBytes( //------------------------------------------------------------------------------ + blink::WebGraphicsContext3D* RendererWebKitPlatformSupportImpl::createOffscreenGraphicsContext3D( +#ifdef ENABLE_EXPLICIT_GL_SHARE_GROUPS + const blink::WebGraphicsContext3D::Attributes& attributes, + blink::WebGraphicsContext3D* share_context) { +#else const blink::WebGraphicsContext3D::Attributes& attributes) { + blink::WebGraphicsContext3D* share_context = NULL; +#endif if (!RenderThreadImpl::current()) return NULL; @@ -966,7 +973,8 @@ RendererWebKitPlatformSupportImpl::createOffscreenGraphicsContext3D( gpu_channel_host.get(), attributes, GURL(attributes.topDocumentURL), - limits); + limits, + static_cast<WebGraphicsContext3DCommandBufferImpl*>(share_context)); } //------------------------------------------------------------------------------ diff --git a/content/renderer/renderer_webkitplatformsupport_impl.h b/content/renderer/renderer_webkitplatformsupport_impl.h index 45f2924..dc0bcda 100644 --- a/content/renderer/renderer_webkitplatformsupport_impl.h +++ b/content/renderer/renderer_webkitplatformsupport_impl.h @@ -133,7 +133,12 @@ class CONTENT_EXPORT RendererWebKitPlatformSupportImpl virtual bool processMemorySizesInBytes( size_t* private_bytes, size_t* shared_bytes); virtual blink::WebGraphicsContext3D* createOffscreenGraphicsContext3D( +#ifdef ENABLE_EXPLICIT_GL_SHARE_GROUPS + const blink::WebGraphicsContext3D::Attributes& attributes, + blink::WebGraphicsContext3D* share_context); +#else const blink::WebGraphicsContext3D::Attributes& attributes); +#endif virtual blink::WebGraphicsContext3DProvider* createSharedOffscreenGraphicsContext3DProvider(); virtual blink::WebCompositorSupport* compositorSupport(); |