diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index 1e758c35a0ddc..e404eaa80b041 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc @@ -398,7 +398,8 @@ CreateGpuProcessViewContext( new WebGraphicsContext3DCommandBufferImpl(surface_id, url, factory, - compositor_impl)); + compositor_impl, + true)); static const size_t kBytesPerPixel = 4; gfx::DeviceDisplayInfo display_info; size_t full_screen_texture_size_in_bytes = diff --git a/content/browser/renderer_host/image_transport_factory_android.cc b/content/browser/renderer_host/image_transport_factory_android.cc index bc0d365d2491a..e7c14062d675e 100644 --- a/content/browser/renderer_host/image_transport_factory_android.cc +++ b/content/browser/renderer_host/image_transport_factory_android.cc @@ -112,7 +112,8 @@ CmdBufferImageTransportFactory::CmdBufferImageTransportFactory() { context_.reset(new WebGraphicsContext3DCommandBufferImpl(0, // offscreen url, factory, - swap_client)); + swap_client, + true)); static const size_t kBytesPerPixel = 4; gfx::DeviceDisplayInfo display_info; size_t full_screen_texture_size_in_bytes = diff --git a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc index edf8de41ca545..0a66e837c8f66 100644 --- a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc +++ b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc @@ -46,6 +46,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( @@ -68,6 +73,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())); @@ -218,7 +243,8 @@ WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl( int surface_id, const GURL& active_url, GpuChannelHostFactory* factory, - const base::WeakPtr& swap_client) + const base::WeakPtr& swap_client, + bool context_for_browser_compositor) : initialize_failed_(false), factory_(factory), visible_(false), @@ -245,6 +271,7 @@ WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl( min_transfer_buffer_size_(0), max_transfer_buffer_size_(0), mapped_memory_limit_(gpu::gles2::GLES2Implementation::kNoLimit), + 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. @@ -260,7 +287,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); } @@ -383,14 +413,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; @@ -457,11 +496,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); + } } } @@ -476,7 +524,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(); } @@ -1595,8 +1647,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 4688d86c0bdd9..7aab858921a06 100644 --- a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h +++ b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h @@ -83,7 +83,8 @@ class WebGraphicsContext3DCommandBufferImpl int surface_id, const GURL& active_url, GpuChannelHostFactory* factory, - const base::WeakPtr& swap_client); + const base::WeakPtr& swap_client, + bool context_for_browser_compositor = false); virtual ~WebGraphicsContext3DCommandBufferImpl(); @@ -766,6 +767,8 @@ class WebGraphicsContext3DCommandBufferImpl size_t max_transfer_buffer_size_; size_t mapped_memory_limit_; + bool context_for_browser_compositor_; + uint32_t flush_id_; };