diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index 8550172bc83a4..8c14b6494c7f9 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc @@ -388,7 +388,8 @@ CreateGpuProcessViewContext( compositor_impl, attributes, false, - limits)); + limits, + true)); } scoped_ptr 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 9b3de30361b89..9af28da029415 100644 --- a/content/browser/renderer_host/image_transport_factory_android.cc +++ b/content/browser/renderer_host/image_transport_factory_android.cc @@ -86,7 +86,8 @@ CmdBufferImageTransportFactory::CmdBufferImageTransportFactory() { swap_client, attrs, false, - limits)); + limits, + true)); context_->setContextLostCallback(context_lost_listener_.get()); if (context_->makeContextCurrent()) context_->pushGroupMarkerEXT( diff --git a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc index 57128427f65e5..05bbd3f37317a 100644 --- a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc +++ b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc @@ -44,6 +44,11 @@ static base::LazyInstance::Leaky static base::LazyInstance > g_all_shared_contexts = LAZY_INSTANCE_INITIALIZER; +static base::LazyInstance::Leaky + g_all_shared_contexts_browser_lock = LAZY_INSTANCE_INITIALIZER; +static base::LazyInstance > + g_all_shared_contexts_browser = LAZY_INSTANCE_INITIALIZER; + namespace { void ClearSharedContextsIfInShareSet( @@ -66,6 +71,26 @@ void ClearSharedContextsIfInShareSet( } } +void ClearSharedContextsIfInShareSetBrowser( + WebGraphicsContext3DCommandBufferImpl* context) { + // If the given context isn't in the share set, that means that it + // or another context it was previously sharing with already + // provoked a lost context. Other contexts might have since been + // successfully created and added to the share set, so do not clear + // out the share set unless we know that all the contexts in there + // are supposed to be lost simultaneously. + base::AutoLock lock(g_all_shared_contexts_browser_lock.Get()); + std::set* share_set = + g_all_shared_contexts_browser.Pointer(); + for (std::set::iterator iter = + share_set->begin(); iter != share_set->end(); ++iter) { + if (context == *iter) { + share_set->clear(); + return; + } + } +} + size_t ClampUint64ToSizeT(uint64 value) { value = std::min(value, static_cast(std::numeric_limits::max())); @@ -231,7 +256,8 @@ WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl( const base::WeakPtr& swap_client, const Attributes& attributes, bool bind_generates_resources, - const SharedMemoryLimits& limits) + const SharedMemoryLimits& limits, + bool context_for_browser_compositor) : initialize_failed_(false), visible_(false), free_command_buffer_when_invisible_(false), @@ -253,6 +279,7 @@ WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl( bind_generates_resources_(bind_generates_resources), use_echo_for_swap_ack_(true), mem_limits_(limits), + context_for_browser_compositor_(context_for_browser_compositor), flush_id_(0) { #if (defined(OS_MACOSX) || defined(OS_WIN)) && !defined(USE_AURA) // Get ViewMsg_SwapBuffers_ACK from browser for single-threaded path. @@ -268,7 +295,10 @@ WebGraphicsContext3DCommandBufferImpl:: real_gl_->SetErrorMessageCallback(NULL); } - { + if (context_for_browser_compositor_) { + base::AutoLock lock(g_all_shared_contexts_browser_lock.Get()); + g_all_shared_contexts_browser.Pointer()->erase(this); + } else { base::AutoLock lock(g_all_shared_contexts_lock.Get()); g_all_shared_contexts.Pointer()->erase(this); } @@ -343,14 +373,23 @@ bool WebGraphicsContext3DCommandBufferImpl::InitializeCommandBuffer( // 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) { - WebGraphicsContext3DCommandBufferImpl* share_group_context = - g_all_shared_contexts.Pointer()->empty() ? - NULL : *g_all_shared_contexts.Pointer()->begin(); - share_group = share_group_context ? - share_group_context->command_buffer_.get() : NULL; + if (context_for_browser_compositor_) { + base::AutoLock lock(g_all_shared_contexts_browser_lock.Get()); + WebGraphicsContext3DCommandBufferImpl* share_group_context = + g_all_shared_contexts_browser.Pointer()->empty() ? + NULL : *g_all_shared_contexts_browser.Pointer()->begin(); + share_group = share_group_context ? + share_group_context->command_buffer_.get() : NULL; + } else { + base::AutoLock lock(g_all_shared_contexts_lock.Get()); + WebGraphicsContext3DCommandBufferImpl* share_group_context = + g_all_shared_contexts.Pointer()->empty() ? + NULL : *g_all_shared_contexts.Pointer()->begin(); + share_group = share_group_context ? + share_group_context->command_buffer_.get() : NULL; + } } std::vector attribs; @@ -417,11 +456,20 @@ bool WebGraphicsContext3DCommandBufferImpl::CreateContext( 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())); - if (!g_all_shared_contexts.Pointer()->empty()) { - share_group = (*g_all_shared_contexts.Pointer()->begin()) - ->GetImplementation()->share_group(); - DCHECK(share_group); + if (context_for_browser_compositor_) { + lock.reset(new base::AutoLock(g_all_shared_contexts_browser_lock.Get())); + if (!g_all_shared_contexts_browser.Pointer()->empty()) { + share_group = (*g_all_shared_contexts_browser.Pointer()->begin()) + ->GetImplementation()->share_group(); + DCHECK(share_group); + } + } else { + lock.reset(new base::AutoLock(g_all_shared_contexts_lock.Get())); + if (!g_all_shared_contexts.Pointer()->empty()) { + share_group = (*g_all_shared_contexts.Pointer()->begin()) + ->GetImplementation()->share_group(); + DCHECK(share_group); + } } } @@ -436,7 +484,11 @@ bool WebGraphicsContext3DCommandBufferImpl::CreateContext( if (attributes_.shareResources) { // Don't add ourselves to the list before others can get to our ShareGroup. - g_all_shared_contexts.Pointer()->insert(this); + if (context_for_browser_compositor_) { + g_all_shared_contexts_browser.Pointer()->insert(this); + } else { + g_all_shared_contexts.Pointer()->insert(this); + } lock.reset(); } @@ -1456,8 +1508,13 @@ void WebGraphicsContext3DCommandBufferImpl::OnContextLost() { if (context_lost_callback_) { context_lost_callback_->onContextLost(); } - if (attributes_.shareResources) - ClearSharedContextsIfInShareSet(this); + if (attributes_.shareResources) { + if (context_for_browser_compositor_) { + ClearSharedContextsIfInShareSetBrowser(this); + } else { + ClearSharedContextsIfInShareSet(this); + } + } if (ShouldUseSwapClient()) swap_client_->OnViewContextSwapBuffersAborted(); } diff --git a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h index 221114a61a187..3df121f606dfc 100644 --- a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h +++ b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h @@ -92,7 +92,8 @@ class WebGraphicsContext3DCommandBufferImpl const base::WeakPtr& swap_client, const Attributes& attributes, bool bind_generates_resources, - const SharedMemoryLimits& limits); + const SharedMemoryLimits& limits, + bool context_for_browser_compositor = false); virtual ~WebGraphicsContext3DCommandBufferImpl(); @@ -753,6 +754,8 @@ class WebGraphicsContext3DCommandBufferImpl bool use_echo_for_swap_ack_; SharedMemoryLimits mem_limits_; + bool context_for_browser_compositor_; + uint32_t flush_id_; };