Cherry-pick: gpu: Use a single container for GLInProcessContext share group

Cherry-pick with conflict of crrev.com/r250765

Conflicts:
	gpu/command_buffer/service/in_process_command_buffer.cc

Original description:

Instead of having two global containers for GLInProcessContext
and InProcessCommandBuffer, use a single one for the former
and pass in the service-side share group while we are holding the
lock anyways.

This makes it simpler to support multiple service threads.

BUG: 13328348

Change-Id: Ia6d5817688e90cbd00d9cc6077d82e59c3933a0d
diff --git a/gpu/command_buffer/client/gl_in_process_context.cc b/gpu/command_buffer/client/gl_in_process_context.cc
index 1bd4c62..3c19c4d 100644
--- a/gpu/command_buffer/client/gl_in_process_context.cc
+++ b/gpu/command_buffer/client/gl_in_process_context.cc
@@ -79,7 +79,6 @@
   scoped_ptr<gles2::GLES2Implementation> gles2_implementation_;
   scoped_ptr<InProcessCommandBuffer> command_buffer_;
 
-  unsigned int share_group_id_;
   bool context_lost_;
   base::Closure context_lost_callback_;
 
@@ -92,7 +91,7 @@
     LAZY_INSTANCE_INITIALIZER;
 
 GLInProcessContextImpl::GLInProcessContextImpl()
-    : share_group_id_(0), context_lost_(false) {}
+    : context_lost_(false) {}
 
 GLInProcessContextImpl::~GLInProcessContextImpl() {
   {
@@ -189,6 +188,7 @@
 
   scoped_ptr<base::AutoLock> scoped_shared_context_lock;
   scoped_refptr<gles2::ShareGroup> share_group;
+  InProcessCommandBuffer* share_command_buffer = NULL;
   if (share_resources) {
     scoped_shared_context_lock.reset(
         new base::AutoLock(g_all_shared_contexts_lock.Get()));
@@ -199,24 +199,21 @@
       const GLInProcessContextImpl* context = *it;
       if (!context->context_lost_) {
         share_group = context->gles2_implementation_->share_group();
+        share_command_buffer = context->command_buffer_.get();
         DCHECK(share_group);
-        share_group_id_ = context->share_group_id_;
+        DCHECK(share_command_buffer);
         break;
       }
-      share_group_id_ = std::max(share_group_id_, context->share_group_id_);
     }
-    if (!share_group && !++share_group_id_)
-        ++share_group_id_;
   }
   if (!command_buffer_->Initialize(surface,
                                    is_offscreen,
-                                   share_resources,
                                    window,
                                    size,
                                    attrib_vector,
                                    gpu_preference,
                                    wrapped_callback,
-                                   share_group_id_)) {
+                                   share_command_buffer)) {
     LOG(ERROR) << "Failed to initialize InProcessCommmandBuffer";
     return false;
   }
diff --git a/gpu/command_buffer/service/in_process_command_buffer.cc b/gpu/command_buffer/service/in_process_command_buffer.cc
index af14778..365e261 100644
--- a/gpu/command_buffer/service/in_process_command_buffer.cc
+++ b/gpu/command_buffer/service/in_process_command_buffer.cc
@@ -43,9 +43,6 @@
 
 namespace {
 
-static base::LazyInstance<std::set<InProcessCommandBuffer*> >
-    g_all_shared_contexts = LAZY_INSTANCE_INITIALIZER;
-
 static bool g_use_virtualized_gl_context = false;
 static bool g_uses_explicit_scheduling = false;
 static GpuMemoryBufferFactory* g_gpu_memory_buffer_factory = NULL;
@@ -251,7 +248,6 @@
 
 InProcessCommandBuffer::InProcessCommandBuffer()
     : context_lost_(false),
-      share_group_id_(0),
       last_put_offset_(-1),
       flush_event_(false, false),
       queue_(CreateSchedulerClient()),
@@ -261,15 +257,6 @@
   Destroy();
 }
 
-bool InProcessCommandBuffer::IsContextLost() {
-  CheckSequencedThread();
-  if (context_lost_ || !command_buffer_) {
-    return true;
-  }
-  CommandBuffer::State state = GetState();
-  return error::IsError(state.error);
-}
-
 void InProcessCommandBuffer::OnResizeView(gfx::Size size, float scale_factor) {
   CheckSequencedThread();
   DCHECK(!surface_->IsOffscreen());
@@ -308,17 +295,14 @@
 bool InProcessCommandBuffer::Initialize(
     scoped_refptr<gfx::GLSurface> surface,
     bool is_offscreen,
-    bool share_resources,
     gfx::AcceleratedWidget window,
     const gfx::Size& size,
     const std::vector<int32>& attribs,
     gfx::GpuPreference gpu_preference,
     const base::Closure& context_lost_callback,
-    unsigned int share_group_id) {
+    InProcessCommandBuffer* share_group) {
 
-  share_resources_ = share_resources;
   context_lost_callback_ = WrapCallback(context_lost_callback);
-  share_group_id_ = share_group_id;
 
   if (surface) {
     // GPU thread must be the same as client thread due to GLSurface not being
@@ -328,8 +312,13 @@
   }
 
   gpu::Capabilities capabilities;
-  InitializeOnGpuThreadParams params(
-      is_offscreen, window, size, attribs, gpu_preference, &capabilities);
+  InitializeOnGpuThreadParams params(is_offscreen,
+                                     window,
+                                     size,
+                                     attribs,
+                                     gpu_preference,
+                                     &capabilities,
+                                     share_group);
 
   base::Callback<bool(void)> init_task =
       base::Bind(&InProcessCommandBuffer::InitializeOnGpuThread,
@@ -351,9 +340,6 @@
     const InitializeOnGpuThreadParams& params) {
   CheckSequencedThread();
   gpu_thread_weak_ptr_ = gpu_thread_weak_ptr_factory_.GetWeakPtr();
-  // Use one share group for all contexts.
-  CR_DEFINE_STATIC_LOCAL(scoped_refptr<gfx::GLShareGroup>, share_group,
-                         (new gfx::GLShareGroup));
 
   DCHECK(params.size.width() >= 0 && params.size.height() >= 0);
 
@@ -374,35 +360,20 @@
     return false;
   }
 
-  InProcessCommandBuffer* context_group = NULL;
-
-  if (share_resources_ && !g_all_shared_contexts.Get().empty()) {
-    DCHECK(share_group_id_);
-    for (std::set<InProcessCommandBuffer*>::iterator it =
-             g_all_shared_contexts.Get().begin();
-         it != g_all_shared_contexts.Get().end();
-         ++it) {
-      if ((*it)->share_group_id_ == share_group_id_) {
-        context_group = *it;
-        DCHECK(context_group->share_resources_);
-        context_lost_ = context_group->IsContextLost();
-        break;
-      }
-    }
-    if (!context_group)
-      share_group = new gfx::GLShareGroup;
-  }
+  gl_share_group_ = params.context_group
+                        ? params.context_group->gl_share_group_.get()
+                        : new gfx::GLShareGroup;
 
   StreamTextureManager* stream_texture_manager = NULL;
 #if defined(OS_ANDROID)
   stream_texture_manager = stream_texture_manager_ =
-      context_group ? context_group->stream_texture_manager_.get()
+      params.context_group ? params.context_group->stream_texture_manager_.get()
                     : new StreamTextureManagerInProcess;
 #endif
 
   bool bind_generates_resource = false;
   decoder_.reset(gles2::GLES2Decoder::Create(
-      context_group ? context_group->decoder_->GetContextGroup()
+      params.context_group ? params.context_group->decoder_->GetContextGroup()
                     : new gles2::ContextGroup(NULL,
                                               NULL,
                                               NULL,
@@ -432,15 +403,15 @@
   }
 
   if (g_use_virtualized_gl_context) {
-    context_ = share_group->GetSharedContext();
+    context_ = gl_share_group_->GetSharedContext();
     if (!context_.get()) {
       context_ = gfx::GLContext::CreateGLContext(
-          share_group.get(), surface_.get(), params.gpu_preference);
-      share_group->SetSharedContext(context_.get());
+          gl_share_group_.get(), surface_.get(), params.gpu_preference);
+      gl_share_group_->SetSharedContext(context_.get());
     }
 
     context_ = new GLContextVirtual(
-        share_group.get(), context_.get(), decoder_->AsWeakPtr());
+        gl_share_group_.get(), context_.get(), decoder_->AsWeakPtr());
     if (context_->Initialize(surface_.get(), params.gpu_preference)) {
       VLOG(1) << "Created virtual GL context.";
     } else {
@@ -448,7 +419,7 @@
     }
   } else {
     context_ = gfx::GLContext::CreateGLContext(
-        share_group.get(), surface_.get(), params.gpu_preference);
+        gl_share_group_.get(), surface_.get(), params.gpu_preference);
   }
 
   if (!context_.get()) {
@@ -490,10 +461,6 @@
         &InProcessCommandBuffer::OnResizeView, gpu_thread_weak_ptr_));
   }
 
-  if (share_resources_) {
-    g_all_shared_contexts.Pointer()->insert(this);
-  }
-
   return true;
 }
 
@@ -521,8 +488,8 @@
   }
   context_ = NULL;
   surface_ = NULL;
+  gl_share_group_ = NULL;
 
-  g_all_shared_contexts.Pointer()->erase(this);
   return true;
 }
 
@@ -539,14 +506,6 @@
   }
 
   context_lost_ = true;
-  if (share_resources_) {
-    for (std::set<InProcessCommandBuffer*>::iterator it =
-             g_all_shared_contexts.Get().begin();
-         it != g_all_shared_contexts.Get().end();
-         ++it) {
-      (*it)->context_lost_ = true;
-    }
-  }
 }
 
 CommandBuffer::State InProcessCommandBuffer::GetStateFast() {
diff --git a/gpu/command_buffer/service/in_process_command_buffer.h b/gpu/command_buffer/service/in_process_command_buffer.h
index b00f25b..bc0ac1a 100644
--- a/gpu/command_buffer/service/in_process_command_buffer.h
+++ b/gpu/command_buffer/service/in_process_command_buffer.h
@@ -28,6 +28,7 @@
 
 namespace gfx {
 class GLContext;
+class GLShareGroup;
 class GLSurface;
 class Size;
 }
@@ -80,13 +81,12 @@
   // a new GLSurface.
   bool Initialize(scoped_refptr<gfx::GLSurface> surface,
                   bool is_offscreen,
-                  bool share_resources,
                   gfx::AcceleratedWidget window,
                   const gfx::Size& size,
                   const std::vector<int32>& attribs,
                   gfx::GpuPreference gpu_preference,
                   const base::Closure& context_lost_callback,
-                  unsigned int share_group_id);
+                  InProcessCommandBuffer* share_group);
   void Destroy();
 
   // CommandBuffer implementation:
@@ -153,26 +153,28 @@
     const std::vector<int32>& attribs;
     gfx::GpuPreference gpu_preference;
     gpu::Capabilities* capabilities;  // Ouptut.
+    InProcessCommandBuffer* context_group;
 
     InitializeOnGpuThreadParams(bool is_offscreen,
                                 gfx::AcceleratedWidget window,
                                 const gfx::Size& size,
                                 const std::vector<int32>& attribs,
                                 gfx::GpuPreference gpu_preference,
-                                gpu::Capabilities* capabilities)
+                                gpu::Capabilities* capabilities,
+                                InProcessCommandBuffer* share_group)
         : is_offscreen(is_offscreen),
           window(window),
           size(size),
           attribs(attribs),
           gpu_preference(gpu_preference),
-          capabilities(capabilities) {}
+          capabilities(capabilities),
+          context_group(share_group) {}
   };
 
   bool InitializeOnGpuThread(const InitializeOnGpuThreadParams& params);
   bool DestroyOnGpuThread();
   void FlushOnGpuThread(int32 put_offset);
   bool MakeCurrent();
-  bool IsContextLost();
   base::Closure WrapCallback(const base::Closure& callback);
   State GetStateFast();
   void QueueTask(const base::Closure& task) { queue_->QueueTask(task); }
@@ -188,14 +190,12 @@
   // Members accessed on the gpu thread (possibly with the exception of
   // creation):
   bool context_lost_;
-  bool share_resources_;
   scoped_ptr<TransferBufferManagerInterface> transfer_buffer_manager_;
   scoped_ptr<GpuScheduler> gpu_scheduler_;
   scoped_ptr<gles2::GLES2Decoder> decoder_;
   scoped_refptr<gfx::GLContext> context_;
   scoped_refptr<gfx::GLSurface> surface_;
   base::Closure context_lost_callback_;
-  unsigned int share_group_id_;
 
   // Members accessed on the client thread:
   State last_state_;
@@ -210,6 +210,7 @@
   State state_after_last_flush_;
   base::Lock state_after_last_flush_lock_;
   scoped_ptr<GpuControl> gpu_control_;
+  scoped_refptr<gfx::GLShareGroup> gl_share_group_;
 
 #if defined(OS_ANDROID)
   scoped_refptr<StreamTextureManagerInProcess> stream_texture_manager_;