Reland 87371 - Support for glSetSurfaceCHROMIUM.

This command allows a previously created GPU surface to be made current for a command buffer. There are no surfaces registered at this point so this command is currently a no-op.
Review URL: http://codereview.chromium.org/7077001
Review URL: http://codereview.chromium.org/7006019

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@87408 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/content/common/gpu/gpu_channel.cc b/content/common/gpu/gpu_channel.cc
index 338d426..5423544 100644
--- a/content/common/gpu/gpu_channel.cc
+++ b/content/common/gpu/gpu_channel.cc
@@ -126,6 +126,14 @@
   gpu_channel_manager_->LoseAllContexts();
 }
 
+gfx::GLSurface* GpuChannel::LookupSurface(int surface_id) {
+  GpuSurfaceStub *surface_stub = surfaces_.Lookup(surface_id);
+  if (!surface_stub)
+    return NULL;
+
+  return surface_stub->surface();
+}
+
 void GpuChannel::CreateViewCommandBuffer(
     gfx::PluginWindowHandle window,
     int32 render_view_id,
@@ -259,7 +267,7 @@
   *route_id = MSG_ROUTING_NONE;
 
 #if defined(ENABLE_GPU)
-  scoped_ptr<gfx::GLSurface> surface(
+  scoped_refptr<gfx::GLSurface> surface(
        gfx::GLSurface::CreateOffscreenGLSurface(size));
   if (!surface.get())
     return;
diff --git a/content/common/gpu/gpu_channel.h b/content/common/gpu/gpu_channel.h
index da12ecdb..0e39636 100644
--- a/content/common/gpu/gpu_channel.h
+++ b/content/common/gpu/gpu_channel.h
@@ -14,6 +14,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/process.h"
 #include "build/build_config.h"
+#include "gpu/command_buffer/service/surface_manager.h"
 #include "content/common/gpu/gpu_command_buffer_stub.h"
 #include "content/common/gpu/gpu_surface_stub.h"
 #include "content/common/message_router.h"
@@ -31,10 +32,15 @@
 class WaitableEvent;
 }
 
+namespace gfx {
+class GLSurface;
+}
+
 // Encapsulates an IPC channel between the GPU process and one renderer
 // process. On the renderer side there's a corresponding GpuChannelHost.
 class GpuChannel : public IPC::Channel::Listener,
                    public IPC::Message::Sender,
+                   public gpu::SurfaceManager,
                    public base::RefCountedThreadSafe<GpuChannel> {
  public:
   // Takes ownership of the renderer process handle.
@@ -86,6 +92,9 @@
 
   void LoseAllContexts();
 
+  // Look up a GLSurface by ID. In this case the ID is the IPC routing ID.
+  gfx::GLSurface* LookupSurface(int surface_id);
+
   // Get the TransportTexture by ID.
   TransportTexture* GetTransportTexture(int32 route_id);
 
diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc
index 531e2ac..b539227 100644
--- a/content/common/gpu/gpu_command_buffer_stub.cc
+++ b/content/common/gpu/gpu_command_buffer_stub.cc
@@ -134,7 +134,9 @@
   if (command_buffer_->Initialize(&shared_memory, size)) {
     gpu::GpuScheduler* parent_processor =
         parent_ ? parent_->scheduler_.get() : NULL;
-    scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(), NULL));
+    scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(),
+                                           channel_,
+                                           NULL));
     if (scheduler_->Initialize(
         handle_,
         initial_size_,
diff --git a/content/common/gpu/gpu_surface_stub.h b/content/common/gpu/gpu_surface_stub.h
index 1a9deb6b8..8776ee0 100644
--- a/content/common/gpu/gpu_surface_stub.h
+++ b/content/common/gpu/gpu_surface_stub.h
@@ -8,8 +8,7 @@
 
 #if defined(ENABLE_GPU)
 
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
+#include "base/memory/ref_counted.h"
 #include "ipc/ipc_channel.h"
 #include "ipc/ipc_message.h"
 #include "ui/gfx/gl/gl_surface.h"
@@ -18,13 +17,14 @@
 
 class GpuSurfaceStub
     : public IPC::Channel::Listener,
-      public IPC::Message::Sender,
-      public base::SupportsWeakPtr<GpuSurfaceStub> {
+      public IPC::Message::Sender {
  public:
   // Takes ownership of surface.
   GpuSurfaceStub(GpuChannel* channel, int route_id, gfx::GLSurface* surface);
   virtual ~GpuSurfaceStub();
 
+  gfx::GLSurface* surface() const { return surface_.get(); }
+
   // IPC::Channel::Listener implementation:
   virtual bool OnMessageReceived(const IPC::Message& message);
 
@@ -40,7 +40,7 @@
   GpuChannel* channel_;
 
   int route_id_;
-  scoped_ptr<gfx::GLSurface> surface_;
+  scoped_refptr<gfx::GLSurface> surface_;
   DISALLOW_COPY_AND_ASSIGN(GpuSurfaceStub);
 };
 
diff --git a/content/gpu/gpu_info_collector.cc b/content/gpu/gpu_info_collector.cc
index 80c98fa..2e4630b2 100644
--- a/content/gpu/gpu_info_collector.cc
+++ b/content/gpu/gpu_info_collector.cc
@@ -18,20 +18,20 @@
 
 namespace {
 
-gfx::GLSurface* InitializeGLSurface() {
-  scoped_ptr<gfx::GLSurface> surface(gfx::GLSurface::CreateOffscreenGLSurface(
-      gfx::Size(1, 1)));
+scoped_refptr<gfx::GLSurface> InitializeGLSurface() {
+  scoped_refptr<gfx::GLSurface> surface(
+      gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1)));
   if (!surface.get()) {
     LOG(ERROR) << "gfx::GLContext::CreateOffscreenGLSurface failed";
     return NULL;
   }
 
-  return surface.release();
+  return surface;
 }
 
-gfx::GLContext* InitializeGLContext(gfx::GLSurface* surface) {
+scoped_refptr<gfx::GLContext> InitializeGLContext(gfx::GLSurface* surface) {
 
-  scoped_ptr<gfx::GLContext> context(gfx::GLContext::CreateGLContext(NULL,
+  scoped_refptr<gfx::GLContext> context(gfx::GLContext::CreateGLContext(NULL,
                                                                      surface));
   if (!context.get()) {
     LOG(ERROR) << "gfx::GLContext::CreateGLContext failed";
@@ -43,7 +43,7 @@
     return NULL;
   }
 
-  return context.release();
+  return context;
 }
 
 std::string GetGLString(unsigned int pname) {
@@ -84,11 +84,11 @@
     return false;
   }
 
-  scoped_ptr<gfx::GLSurface> surface(InitializeGLSurface());
+  scoped_refptr<gfx::GLSurface> surface(InitializeGLSurface());
   if (!surface.get())
     return false;
 
-  scoped_ptr<gfx::GLContext> context(InitializeGLContext(surface.get()));
+  scoped_refptr<gfx::GLContext> context(InitializeGLContext(surface.get()));
   if (!context.get())
     return false;
 
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index cf36aded..4d8d924 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -214,6 +214,7 @@
 GL_APICALL void         GL_APIENTRY glSetLatchCHROMIUM (GLuint latch_id);
 GL_APICALL void         GL_APIENTRY glWaitLatchCHROMIUM (GLuint latch_id);
 GL_APICALL void         GL_APIENTRY glRateLimitOffscreenContextCHROMIUM (void);
+GL_APICALL void         GL_APIENTRY glSetSurfaceCHROMIUM (GLint surface_id);
 """
 
 # This is the list of all commmands that will be generated and their Id.
@@ -419,6 +420,7 @@
   'RequestExtensionCHROMIUM':                                  450,
   'SetLatchCHROMIUM':                                          451,
   'WaitLatchCHROMIUM':                                         452,
+  'SetSurfaceCHROMIUM':                                        453,
 }
 
 # This is a list of enum names and their valid values. It is used to map
@@ -1490,6 +1492,12 @@
     'decoder_func': 'DoReleaseShaderCompiler',
     'unit_test': False,
   },
+  'SetSurfaceCHROMIUM': {
+    'decoder_func': 'DoSetSurfaceCHROMIUM',
+    'extension': True,
+    'chromium': True,
+    'unit_test': False,
+  },
   'ShaderBinary': {'type': 'Custom'},
   'ShaderSource': {
     'type': 'Manual',
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h
index 889a243..663d162 100644
--- a/gpu/command_buffer/client/gles2_c_lib_autogen.h
+++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -889,6 +889,10 @@
   GPU_CLIENT_LOG("RateLimitOffscreenContextCHROMIUM" << "(" << ")");
   gles2::GetGLContext()->RateLimitOffscreenContextCHROMIUM();
 }
+void GLES2SetSurfaceCHROMIUM(GLint surface_id) {
+  GPU_CLIENT_LOG("SetSurfaceCHROMIUM" << "(" << surface_id << ")");
+  gles2::GetGLContext()->SetSurfaceCHROMIUM(surface_id);
+}
 
 #endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_C_LIB_AUTOGEN_H_
 
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
index e6568da..c8deb23 100644
--- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
+++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -1227,5 +1227,10 @@
     c.Init(latch_id);
   }
 
+  void SetSurfaceCHROMIUM(GLint surface_id) {
+    gles2::SetSurfaceCHROMIUM& c = GetCmdSpace<gles2::SetSurfaceCHROMIUM>();
+    c.Init(surface_id);
+  }
+
 #endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_CMD_HELPER_AUTOGEN_H_
 
diff --git a/gpu/command_buffer/client/gles2_demo.cc b/gpu/command_buffer/client/gles2_demo.cc
index 78768dd..90825b09 100644
--- a/gpu/command_buffer/client/gles2_demo.cc
+++ b/gpu/command_buffer/client/gles2_demo.cc
@@ -56,7 +56,9 @@
   if (!command_buffer->Initialize(size))
     return NULL;
 
-  GpuScheduler* gpu_scheduler = new GpuScheduler(command_buffer.get(), NULL);
+  GpuScheduler* gpu_scheduler = new GpuScheduler(command_buffer.get(),
+                                                 NULL,
+                                                 NULL);
   if (!gpu_scheduler->Initialize(reinterpret_cast<HWND>(hwnd),
                                  gfx::Size(),
                                  gpu::gles2::DisallowedExtensions(),
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h
index 97704a1..f389920 100644
--- a/gpu/command_buffer/client/gles2_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -899,5 +899,9 @@
 
 void RateLimitOffscreenContextCHROMIUM();
 
+void SetSurfaceCHROMIUM(GLint surface_id) {
+  helper_->SetSurfaceCHROMIUM(surface_id);
+}
+
 #endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_AUTOGEN_H_
 
diff --git a/gpu/command_buffer/common/gl_mock.h b/gpu/command_buffer/common/gl_mock.h
index 1a7e474..b91cb5b 100644
--- a/gpu/command_buffer/common/gl_mock.h
+++ b/gpu/command_buffer/common/gl_mock.h
@@ -426,6 +426,8 @@
   MOCK_METHOD1(IsFenceNV, GLboolean(GLuint fence));
 
   MOCK_METHOD3(GetFenceivNV, void(GLuint fence, GLenum pname, GLint *params));
+
+  MOCK_METHOD1(SetSurfaceCHROMIUM, void(GLuint));
 };
 
 }  // namespace gfx
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
index 0536887..67bbc361 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -8979,6 +8979,40 @@
 COMPILE_ASSERT(offsetof(WaitLatchCHROMIUM, latch_id) == 4,
                OffsetOf_WaitLatchCHROMIUM_latch_id_not_4);
 
+struct SetSurfaceCHROMIUM {
+  typedef SetSurfaceCHROMIUM ValueType;
+  static const CommandId kCmdId = kSetSurfaceCHROMIUM;
+  static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+
+  static uint32 ComputeSize() {
+    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  }
+
+  void SetHeader() {
+    header.SetCmd<ValueType>();
+  }
+
+  void Init(GLint _surface_id) {
+    SetHeader();
+    surface_id = _surface_id;
+  }
+
+  void* Set(void* cmd, GLint _surface_id) {
+    static_cast<ValueType*>(cmd)->Init(_surface_id);
+    return NextCmdAddress<ValueType>(cmd);
+  }
+
+  gpu::CommandHeader header;
+  int32 surface_id;
+};
+
+COMPILE_ASSERT(sizeof(SetSurfaceCHROMIUM) == 8,
+               Sizeof_SetSurfaceCHROMIUM_is_not_8);
+COMPILE_ASSERT(offsetof(SetSurfaceCHROMIUM, header) == 0,
+               OffsetOf_SetSurfaceCHROMIUM_header_not_0);
+COMPILE_ASSERT(offsetof(SetSurfaceCHROMIUM, surface_id) == 4,
+               OffsetOf_SetSurfaceCHROMIUM_surface_id_not_4);
+
 
 #endif  // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_AUTOGEN_H_
 
diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
index 77660e2f..0f18f941 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -3534,5 +3534,18 @@
   EXPECT_EQ(static_cast<GLuint>(11), cmd.latch_id);
 }
 
+TEST(GLES2FormatTest, SetSurfaceCHROMIUM) {
+  SetSurfaceCHROMIUM cmd = { { 0 } };
+  void* next_cmd = cmd.Set(
+      &cmd,
+      static_cast<GLint>(11));
+  EXPECT_EQ(static_cast<uint32>(SetSurfaceCHROMIUM::kCmdId),
+            cmd.header.command);
+  EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+  EXPECT_EQ(static_cast<char*>(next_cmd),
+            reinterpret_cast<char*>(&cmd) + sizeof(cmd));
+  EXPECT_EQ(static_cast<GLint>(11), cmd.surface_id);
+}
+
 #endif  // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_TEST_AUTOGEN_H_
 
diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
index 7566beb..5a3dc2d8 100644
--- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -205,6 +205,7 @@
   OP(RequestExtensionCHROMIUM)                                 /* 450 */ \
   OP(SetLatchCHROMIUM)                                         /* 451 */ \
   OP(WaitLatchCHROMIUM)                                        /* 452 */ \
+  OP(SetSurfaceCHROMIUM)                                       /* 453 */ \
 
 enum CommandId {
   kStartPoint = cmd::kLastCommonId,  // All GLES2 commands start after this.
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 25b66962..dec7c34 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -34,6 +34,7 @@
 #include "gpu/command_buffer/service/renderbuffer_manager.h"
 #include "gpu/command_buffer/service/shader_manager.h"
 #include "gpu/command_buffer/service/shader_translator.h"
+#include "gpu/command_buffer/service/surface_manager.h"
 #include "gpu/command_buffer/service/texture_manager.h"
 #include "gpu/GLES2/gles2_command_buffer.h"
 #include "ui/gfx/gl/gl_context.h"
@@ -661,7 +662,8 @@
 class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
                          public GLES2Decoder {
  public:
-  explicit GLES2DecoderImpl(ContextGroup* group);
+  explicit GLES2DecoderImpl(SurfaceManager* surface_manager,
+                            ContextGroup* group);
 
   // Overridden from AsyncAPIInterface.
   virtual Error DoCommand(unsigned int command,
@@ -672,8 +674,8 @@
   virtual const char* GetCommandName(unsigned int command_id) const;
 
   // Overridden from GLES2Decoder.
-  virtual bool Initialize(gfx::GLSurface* surface,
-                          gfx::GLContext* context,
+  virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
+                          const scoped_refptr<gfx::GLContext>& context,
                           const gfx::Size& size,
                           const DisallowedExtensions& disallowed_extensions,
                           const char* allowed_extensions,
@@ -1229,6 +1231,8 @@
 
   void DoResizeCHROMIUM(GLuint width, GLuint height);
 
+  void DoSetSurfaceCHROMIUM(GLint surface_id);
+
   // Gets the number of values that will be returned by glGetXXX. Returns
   // false if pname is unknown.
   bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
@@ -1339,9 +1343,12 @@
 
   #undef GLES2_CMD_OP
 
+  // Maps surface IDs to GLSurface.
+  gpu::SurfaceManager* surface_manager_;
+
   // The GL context this decoder renders to on behalf of the client.
-  scoped_ptr<gfx::GLSurface> surface_;
-  scoped_ptr<gfx::GLContext> context_;
+  scoped_refptr<gfx::GLSurface> surface_;
+  scoped_refptr<gfx::GLContext> context_;
 
   // The ContextGroup for this decoder uses to track resources.
   ContextGroup::Ref group_;
@@ -1767,12 +1774,15 @@
   return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
 }
 
-GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
-  return new GLES2DecoderImpl(group);
+GLES2Decoder* GLES2Decoder::Create(SurfaceManager* surface_manager,
+                                   ContextGroup* group) {
+  return new GLES2DecoderImpl(surface_manager, group);
 }
 
-GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
+GLES2DecoderImpl::GLES2DecoderImpl(SurfaceManager* surface_manager,
+                                   ContextGroup* group)
     : GLES2Decoder(),
+      surface_manager_(surface_manager),
       group_(ContextGroup::Ref(group ? group : new ContextGroup())),
       error_bits_(0),
       util_(0),  // TODO(gman): Set to actual num compress texture formats.
@@ -1831,8 +1841,8 @@
 }
 
 bool GLES2DecoderImpl::Initialize(
-    gfx::GLSurface* surface,
-    gfx::GLContext* context,
+    const scoped_refptr<gfx::GLSurface>& surface,
+    const scoped_refptr<gfx::GLContext>& context,
     const gfx::Size& size,
     const DisallowedExtensions& disallowed_extensions,
     const char* allowed_extensions,
@@ -1842,13 +1852,15 @@
   DCHECK(context);
   DCHECK(!context_.get());
 
-  // Take ownership of the GLSurface. TODO(apatrick): the decoder should not
-  // own the surface. It should be possible to freely switch the surface the
-  // context renders to.
-  surface_.reset(surface);
+  // Take ownership of the GLSurface. TODO(apatrick): once the parent / child
+  // context is retired, the decoder should not take an initial surface as
+  // an argument to this function.
+  // Maybe create a short lived offscreen GLSurface for the purpose of
+  // initializing the decoder's GLContext.
+  surface_ = surface;
 
   // Take ownership of the GLContext.
-  context_.reset(context);
+  context_ = context;
 
   // Keep only a weak pointer to the parent so we don't unmap its client
   // frame buffer after it has been destroyed.
@@ -2567,7 +2579,7 @@
 
   if (context_.get())
     context_->Destroy();
-  context_.reset();
+  context_ = NULL;
 
   offscreen_target_frame_buffer_.reset();
   offscreen_target_color_texture_.reset();
@@ -2627,6 +2639,14 @@
   }
 }
 
+void GLES2DecoderImpl::DoSetSurfaceCHROMIUM(GLint surface_id) {
+  gfx::GLSurface* surface = surface_manager_->LookupSurface(surface_id);
+  if (!surface)
+    return;
+
+  surface_ = surface;
+}
+
 const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
   if (command_id > kStartPoint && command_id < kNumCommands) {
     return gles2::GetCommandName(static_cast<CommandId>(command_id));
@@ -6428,7 +6448,9 @@
   if (!latch) {
     return error::kOutOfBounds;
   }
-  base::subtle::NoBarrier_Store(latch, 1);
+  base::subtle::Atomic32 old =
+      base::subtle::NoBarrier_CompareAndSwap(latch, 0, 1);
+  DCHECK(old == 0);
   if (!latch_callback_.is_null())
     latch_callback_.Run(true);
   return error::kNoError;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h
index 7236cc0..699f85e 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.h
@@ -22,6 +22,8 @@
 
 namespace gpu {
 
+class SurfaceManager;
+
 namespace gles2 {
 
 class ContextGroup;
@@ -40,7 +42,8 @@
   typedef error::Error Error;
 
   // Creates a decoder.
-  static GLES2Decoder* Create(ContextGroup* group);
+  static GLES2Decoder* Create(SurfaceManager* surface_manager,
+                              ContextGroup* group);
 
   virtual ~GLES2Decoder();
 
@@ -68,8 +71,8 @@
   //      parent's namespace.
   // Returns:
   //   true if successful.
-  virtual bool Initialize(gfx::GLSurface* surface,
-                          gfx::GLContext* context,
+  virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
+                          const scoped_refptr<gfx::GLContext>& context,
                           const gfx::Size& size,
                           const DisallowedExtensions& disallowed_extensions,
                           const char* allowed_extensions,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
index 2ae8a034..9f7711a 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -2600,5 +2600,12 @@
   return error::kNoError;
 }
 
+error::Error GLES2DecoderImpl::HandleSetSurfaceCHROMIUM(
+    uint32 immediate_data_size, const gles2::SetSurfaceCHROMIUM& c) {
+  GLint surface_id = static_cast<GLint>(c.surface_id);
+  DoSetSurfaceCHROMIUM(surface_id);
+  return error::kNoError;
+}
+
 #endif  // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_AUTOGEN_H_
 
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
index 425fdce7..f775625 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
@@ -30,8 +30,8 @@
   virtual ~MockGLES2Decoder();
 
   MOCK_METHOD8(Initialize,
-               bool(gfx::GLSurface* surface,
-                    gfx::GLContext* context,
+               bool(const scoped_refptr<gfx::GLSurface>& surface,
+                    const scoped_refptr<gfx::GLContext>& context,
                     const gfx::Size& size,
                     const DisallowedExtensions& disallowed_extensions,
                     const char* allowed_extensions,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
index 298640a..274d495 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
@@ -16,6 +16,7 @@
 #include "gpu/command_buffer/service/test_helper.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/gl/gl_implementation.h"
+#include "ui/gfx/gl/gl_surface_stub.h"
 
 using ::gfx::MockGLInterface;
 using ::testing::_;
@@ -2933,6 +2934,46 @@
   EXPECT_EQ(0, latches[kLastValidLatchId]);
 }
 
+TEST_F(GLES2DecoderTest, SetSurfaceCHROMIUMChangesSurfaceForExistentSurface) {
+  const int kSurfaceId = 1;
+  scoped_refptr<gfx::GLSurfaceStub> surface(new gfx::GLSurfaceStub);
+
+  EXPECT_CALL(*surface_manager_.get(), LookupSurface(kSurfaceId))
+      .WillOnce(Return(surface.get()))
+      .RetiresOnSaturation();
+
+  SetSurfaceCHROMIUM cmd;
+  cmd.Init(kSurfaceId);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+
+  EXPECT_EQ(surface.get(), decoder_->GetGLSurface());
+}
+
+TEST_F(GLES2DecoderTest,
+    SetSurfaceCHROMIUMDoesNotChangeSurfaceWhenSurfaceDoesNotExist) {
+  const int kExistentSurfaceId = 1;
+  const int kNonexistentSurfaceId = 2;
+  scoped_refptr<gfx::GLSurfaceStub> surface(new gfx::GLSurfaceStub);
+
+  EXPECT_CALL(*surface_manager_.get(), LookupSurface(kExistentSurfaceId))
+      .WillOnce(Return(surface.get()))
+      .RetiresOnSaturation();
+
+  EXPECT_CALL(*surface_manager_.get(), LookupSurface(kNonexistentSurfaceId))
+      .WillOnce(Return(static_cast<gfx::GLSurface*>(NULL)))
+      .RetiresOnSaturation();
+
+  SetSurfaceCHROMIUM cmd;
+  cmd.Init(kExistentSurfaceId);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+
+  cmd.Init(kNonexistentSurfaceId);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+
+  EXPECT_EQ(surface.get(), decoder_->GetGLSurface());
+}
+
+
 // TODO(gman): BufferData
 
 // TODO(gman): BufferDataImmediate
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h
index 72cd0c39..94c5ffc 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h
@@ -10,5 +10,6 @@
 
 // TODO(gman): WaitLatchCHROMIUM
 
+// TODO(gman): SetSurfaceCHROMIUM
 #endif  // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_
 
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
index a38ab8b..7dbc98c 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
@@ -55,6 +55,7 @@
     const char* extensions, bool has_alpha_backbuffer) {
   gl_.reset(new StrictMock<MockGLInterface>());
   ::gfx::GLInterface::SetGLInterface(gl_.get());
+  surface_manager_.reset(new StrictMock<MockSurfaceManager>);
   group_ = ContextGroup::Ref(new ContextGroup());
 
   InSequence sequence;
@@ -133,7 +134,7 @@
 
   context_ = new gfx::GLContextStub;
 
-  decoder_.reset(GLES2Decoder::Create(group_.get()));
+  decoder_.reset(GLES2Decoder::Create(surface_manager_.get(), group_.get()));
   decoder_->Initialize(
       surface_, context_, surface_->GetSize(), DisallowedExtensions(),
       NULL, std::vector<int32>(), NULL, 0);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
index dc195c8..d939e4f8 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
@@ -16,6 +16,7 @@
 #include "gpu/command_buffer/service/program_manager.h"
 #include "gpu/command_buffer/service/renderbuffer_manager.h"
 #include "gpu/command_buffer/service/shader_manager.h"
+#include "gpu/command_buffer/service/surface_manager_mock.h"
 #include "gpu/command_buffer/service/texture_manager.h"
 #include "gpu/GLES2/gles2_command_buffer.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -256,9 +257,10 @@
 
   // Use StrictMock to make 100% sure we know how GL will be called.
   scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_;
-  gfx::GLSurfaceStub* surface_;
-  gfx::GLContextStub* context_;
+  scoped_refptr<gfx::GLSurfaceStub> surface_;
+  scoped_refptr<gfx::GLContextStub> context_;
   scoped_ptr<GLES2Decoder> decoder_;
+  scoped_ptr<MockSurfaceManager> surface_manager_;
 
   GLuint client_buffer_id_;
   GLuint client_framebuffer_id_;
diff --git a/gpu/command_buffer/service/gpu_scheduler.cc b/gpu/command_buffer/service/gpu_scheduler.cc
index 4c54773..151ff9a 100644
--- a/gpu/command_buffer/service/gpu_scheduler.cc
+++ b/gpu/command_buffer/service/gpu_scheduler.cc
@@ -19,6 +19,7 @@
 namespace gpu {
 
 GpuScheduler::GpuScheduler(CommandBuffer* command_buffer,
+                           SurfaceManager* surface_manager,
                            gles2::ContextGroup* group)
     : command_buffer_(command_buffer),
       commands_per_update_(100),
@@ -29,7 +30,7 @@
 #endif
       method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
   DCHECK(command_buffer);
-  decoder_.reset(gles2::GLES2Decoder::Create(group));
+  decoder_.reset(gles2::GLES2Decoder::Create(surface_manager, group));
   decoder_->set_engine(this);
 }
 
@@ -55,8 +56,8 @@
 }
 
 bool GpuScheduler::InitializeCommon(
-    gfx::GLSurface* surface,
-    gfx::GLContext* context,
+    const scoped_refptr<gfx::GLSurface>& surface,
+    const scoped_refptr<gfx::GLContext>& context,
     const gfx::Size& size,
     const gles2::DisallowedExtensions& disallowed_extensions,
     const char* allowed_extensions,
diff --git a/gpu/command_buffer/service/gpu_scheduler.h b/gpu/command_buffer/service/gpu_scheduler.h
index ebbcc88..d75beae 100644
--- a/gpu/command_buffer/service/gpu_scheduler.h
+++ b/gpu/command_buffer/service/gpu_scheduler.h
@@ -40,7 +40,9 @@
 class GpuScheduler : public CommandBufferEngine {
  public:
   // If a group is not passed in one will be created.
-  GpuScheduler(CommandBuffer* command_buffer, gles2::ContextGroup* group);
+  GpuScheduler(CommandBuffer* command_buffer,
+               SurfaceManager* surface_manager,
+               gles2::ContextGroup* group);
 
   // This constructor is for unit tests.
   GpuScheduler(CommandBuffer* command_buffer,
@@ -139,8 +141,8 @@
  protected:
   // Perform common initialization. Takes ownership of GLSurface and GLContext.
   bool InitializeCommon(
-      gfx::GLSurface* surface,
-      gfx::GLContext* context,
+      const scoped_refptr<gfx::GLSurface>& surface,
+      const scoped_refptr<gfx::GLContext>& context,
       const gfx::Size& size,
       const gles2::DisallowedExtensions& disallowed_extensions,
       const char* allowed_extensions,
diff --git a/gpu/command_buffer/service/gpu_scheduler_linux.cc b/gpu/command_buffer/service/gpu_scheduler_linux.cc
index 3ed89e4..f1d49da 100644
--- a/gpu/command_buffer/service/gpu_scheduler_linux.cc
+++ b/gpu/command_buffer/service/gpu_scheduler_linux.cc
@@ -31,13 +31,13 @@
   }
 
   // Create either a view or pbuffer based GLSurface.
-  scoped_ptr<gfx::GLSurface> surface;
+  scoped_refptr<gfx::GLSurface> surface;
   if (window) {
     DCHECK(!parent_handle);
 
-    surface.reset(gfx::GLSurface::CreateViewGLSurface(window));
+    surface = gfx::GLSurface::CreateViewGLSurface(window);
   } else {
-    surface.reset(gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1)));
+    surface = gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1));
   }
 
   if (!surface.get()) {
@@ -47,7 +47,7 @@
   }
 
   // Create a GLContext and attach the surface.
-  scoped_ptr<gfx::GLContext> context(
+  scoped_refptr<gfx::GLContext> context(
       gfx::GLContext::CreateGLContext(parent_context, surface.get()));
   if (!context.get()) {
     LOG(ERROR) << "CreateGLContext failed.\n";
@@ -55,8 +55,8 @@
     return false;
   }
 
-  return InitializeCommon(surface.release(),
-                          context.release(),
+  return InitializeCommon(surface,
+                          context,
                           size,
                           disallowed_extensions,
                           allowed_extensions,
diff --git a/gpu/command_buffer/service/gpu_scheduler_mac.cc b/gpu/command_buffer/service/gpu_scheduler_mac.cc
index 1e323ec..449a90f 100644
--- a/gpu/command_buffer/service/gpu_scheduler_mac.cc
+++ b/gpu/command_buffer/service/gpu_scheduler_mac.cc
@@ -29,7 +29,7 @@
     DCHECK(parent_context);
   }
 
-  scoped_ptr<gfx::GLSurface> surface(
+  scoped_refptr<gfx::GLSurface> surface(
       gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1)));
   if (!surface.get()) {
     LOG(ERROR) << "CreateOffscreenGLSurface failed.\n";
@@ -38,7 +38,7 @@
   }
 
   // Create a GLContext and attach the surface.
-  scoped_ptr<gfx::GLContext> context(
+  scoped_refptr<gfx::GLContext> context(
       gfx::GLContext::CreateGLContext(parent_context, surface.get()));
   if (!context.get()) {
     LOG(ERROR) << "CreateGLContext failed.\n";
@@ -66,8 +66,8 @@
     }
   }
 
-  return InitializeCommon(surface.release(),
-                          context.release(),
+  return InitializeCommon(surface,
+                          context,
                           size,
                           disallowed_extensions,
                           allowed_extensions,
diff --git a/gpu/command_buffer/service/gpu_scheduler_win.cc b/gpu/command_buffer/service/gpu_scheduler_win.cc
index a6dcc73b..81ab10b 100644
--- a/gpu/command_buffer/service/gpu_scheduler_win.cc
+++ b/gpu/command_buffer/service/gpu_scheduler_win.cc
@@ -32,11 +32,11 @@
   }
 
   // Create either a view or pbuffer based GLSurface.
-  scoped_ptr<gfx::GLSurface> surface;
+  scoped_refptr<gfx::GLSurface> surface;
   if (window) {
-    surface.reset(gfx::GLSurface::CreateViewGLSurface(window));
+    surface = gfx::GLSurface::CreateViewGLSurface(window);
   } else {
-    surface.reset(gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1)));
+    surface = gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1));
   }
 
   if (!surface.get()) {
@@ -46,7 +46,7 @@
   }
 
   // Create a GLContext and attach the surface.
-  scoped_ptr<gfx::GLContext> context(
+  scoped_refptr<gfx::GLContext> context(
       gfx::GLContext::CreateGLContext(parent_context, surface.get()));
   if (!context.get()) {
     LOG(ERROR) << "CreateGLContext failed.\n";
@@ -54,8 +54,8 @@
     return false;
   }
 
-  return InitializeCommon(surface.release(),
-                          context.release(),
+  return InitializeCommon(surface,
+                          context,
                           size,
                           disallowed_extensions,
                           allowed_extensions,
diff --git a/gpu/command_buffer/service/surface_manager.cc b/gpu/command_buffer/service/surface_manager.cc
new file mode 100644
index 0000000..2fca939
--- /dev/null
+++ b/gpu/command_buffer/service/surface_manager.cc
@@ -0,0 +1,15 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/command_buffer/service/surface_manager.h"
+
+namespace gpu {
+
+SurfaceManager::SurfaceManager() {
+}
+
+SurfaceManager::~SurfaceManager() {
+}
+
+}  // namespace gpu
diff --git a/gpu/command_buffer/service/surface_manager.h b/gpu/command_buffer/service/surface_manager.h
new file mode 100644
index 0000000..4caa4ac
--- /dev/null
+++ b/gpu/command_buffer/service/surface_manager.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GPU_COMMAND_BUFFER_SERVICE_SURFACE_MANAGER_H_
+#define GPU_COMMAND_BUFFER_SERVICE_SURFACE_MANAGER_H_
+
+#include "base/basictypes.h"
+
+namespace gfx {
+class GLSurface;
+}
+
+namespace gpu {
+
+// Interface used to get the GLSurface corresponding to an ID communicated
+// through the command buffer.
+class SurfaceManager {
+ public:
+  SurfaceManager();
+  virtual ~SurfaceManager();
+
+  virtual gfx::GLSurface* LookupSurface(int id) = 0;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SurfaceManager);
+};
+
+}  // namespace gpu
+
+#endif  // GPU_COMMAND_BUFFER_SERVICE_SURFACE_MANAGER_H_
diff --git a/gpu/command_buffer/service/surface_manager_mock.h b/gpu/command_buffer/service/surface_manager_mock.h
new file mode 100644
index 0000000..f707ed8
--- /dev/null
+++ b/gpu/command_buffer/service/surface_manager_mock.h
@@ -0,0 +1,23 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GPU_COMMAND_BUFFER_SERVICE_SURFACE_MANAGER_MOCK_H_
+#define GPU_COMMAND_BUFFER_SERVICE_SURFACE_MANAGER_MOCK_H_
+
+#include "gpu/command_buffer/service/surface_manager.h"
+
+namespace gpu {
+
+class MockSurfaceManager : public SurfaceManager {
+ public:
+  MockSurfaceManager() {}
+  MOCK_METHOD1(LookupSurface, gfx::GLSurface*(int id));
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MockSurfaceManager);
+};
+
+}  // namespace gpu
+
+#endif  // GPU_COMMAND_BUFFER_SERVICE_SURFACE_MANAGER_MOCK_H_
diff --git a/gpu/demos/framework/window.cc b/gpu/demos/framework/window.cc
index a0eedcc..4cbfbf6 100644
--- a/gpu/demos/framework/window.cc
+++ b/gpu/demos/framework/window.cc
@@ -60,7 +60,7 @@
   }
 
   GpuScheduler* gpu_scheduler(
-      new GpuScheduler(command_buffer.get(), NULL));
+      new GpuScheduler(command_buffer.get(), NULL, NULL));
   if (!gpu_scheduler->Initialize(hwnd, gfx::Size(),
                                  gpu::gles2::DisallowedExtensions(),
                                  NULL, std::vector<int32>(),
diff --git a/gpu/gles2_conform_support/egl/display.cc b/gpu/gles2_conform_support/egl/display.cc
index 7bfded1..2308196 100644
--- a/gpu/gles2_conform_support/egl/display.cc
+++ b/gpu/gles2_conform_support/egl/display.cc
@@ -109,7 +109,7 @@
   using gpu::GpuScheduler;
   std::vector<int32> attribs;
   scoped_ptr<GpuScheduler> gpu_scheduler(
-      new GpuScheduler(command_buffer_.get(), NULL));
+      new GpuScheduler(command_buffer_.get(), NULL, NULL));
   if (!gpu_scheduler->Initialize(
       win, gfx::Size(), gpu::gles2::DisallowedExtensions(), NULL,
       attribs, NULL, 0))
diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp
index f59e6f9..0a5dd31 100644
--- a/gpu/gpu.gyp
+++ b/gpu/gpu.gyp
@@ -226,6 +226,8 @@
         'command_buffer/service/shader_manager.cc',
         'command_buffer/service/shader_translator.h',
         'command_buffer/service/shader_translator.cc',
+        'command_buffer/service/surface_manager.cc',
+        'command_buffer/service/surface_manager.h',
         'command_buffer/service/texture_manager.h',
         'command_buffer/service/texture_manager.cc',
       ],
@@ -293,6 +295,7 @@
         'command_buffer/service/renderbuffer_manager_unittest.cc',
         'command_buffer/service/shader_manager_unittest.cc',
         'command_buffer/service/shader_translator_unittest.cc',
+        'command_buffer/service/surface_manager_mock.h',
         'command_buffer/service/test_helper.cc',
         'command_buffer/service/test_helper.h',
         'command_buffer/service/texture_manager_unittest.cc',
diff --git a/ui/gfx/compositor/compositor_gl.cc b/ui/gfx/compositor/compositor_gl.cc
index cacf54bf..7e6e297 100644
--- a/ui/gfx/compositor/compositor_gl.cc
+++ b/ui/gfx/compositor/compositor_gl.cc
@@ -71,8 +71,8 @@
   bool InitShaders();
 
   // The GL context used for compositing.
-  scoped_ptr<gfx::GLSurface> gl_surface_;
-  scoped_ptr<gfx::GLContext> gl_context_;
+  scoped_refptr<gfx::GLSurface> gl_surface_;
+  scoped_refptr<gfx::GLContext> gl_context_;
   gfx::Size size_;
 
   // Shader program, attributes and uniforms.
@@ -205,8 +205,8 @@
 
 CompositorGL::CompositorGL(gfx::AcceleratedWidget widget)
     : started_(false) {
-  gl_surface_.reset(gfx::GLSurface::CreateViewGLSurface(widget));
-  gl_context_.reset(gfx::GLContext::CreateGLContext(NULL, gl_surface_.get())),
+  gl_surface_ = gfx::GLSurface::CreateViewGLSurface(widget);
+  gl_context_ = gfx::GLContext::CreateGLContext(NULL, gl_surface_.get());
   gl_context_->MakeCurrent(gl_surface_.get());
   if (!InitShaders())
     LOG(ERROR) << "Unable to initialize shaders (context = "
@@ -372,8 +372,8 @@
   void RestoreTransform() OVERRIDE;
 
   // The GL context used for compositing.
-  scoped_ptr<gfx::GLSurface> gl_surface_;
-  scoped_ptr<gfx::GLContext> gl_context_;
+  scoped_refptr<gfx::GLSurface> gl_surface_;
+  scoped_refptr<gfx::GLContext> gl_context_;
 
   // Keep track of whether compositing has started or not.
   bool started_;
@@ -383,8 +383,8 @@
 
 CompositorGL::CompositorGL(gfx::AcceleratedWidget widget)
     : started_(false) {
-  gl_surface_.reset(gfx::GLSurface::CreateViewGLSurface(widget));
-  gl_context_.reset(gfx::GLContext::CreateGLContext(NULL, gl_surface_.get()));
+  gl_surface_ = gfx::GLSurface::CreateViewGLSurface(widget);
+  gl_context_ = gfx::GLContext::CreateGLContext(NULL, gl_surface_.get());
 }
 
 void CompositorGL::NotifyStart() {
diff --git a/ui/gfx/gl/gl_context.cc b/ui/gfx/gl/gl_context.cc
index 6391dc5a..9cf1e40 100644
--- a/ui/gfx/gl/gl_context.cc
+++ b/ui/gfx/gl/gl_context.cc
@@ -13,6 +13,12 @@
 
 namespace gfx {
 
+GLContext::GLContext() {
+}
+
+GLContext::~GLContext() {
+}
+
 std::string GLContext::GetExtensions() {
   DCHECK(IsCurrent(NULL));
   const char* ext = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
diff --git a/ui/gfx/gl/gl_context.h b/ui/gfx/gl/gl_context.h
index 45b944c..77f167f 100644
--- a/ui/gfx/gl/gl_context.h
+++ b/ui/gfx/gl/gl_context.h
@@ -9,16 +9,16 @@
 #include <string>
 
 #include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
 
 namespace gfx {
 
 class GLSurface;
 
 // Encapsulates an OpenGL context, hiding platform specific management.
-class GLContext {
+class GLContext : public base::RefCounted<GLContext> {
  public:
-  GLContext() {}
-  virtual ~GLContext() {}
+  GLContext();
 
   // Initializes the GL context to be compatible with the given surface. The GL
   // context can be made with other surface's of the same type. The compatible
@@ -56,12 +56,17 @@
   // Create a GL context that is compatible with the given surface.
   // |share_context|, if non-NULL, is a context which the
   // internally created OpenGL context shares textures and other resources.
-  static GLContext* CreateGLContext(GLContext* shared_context,
-                                    GLSurface* compatible_surface);
+  static scoped_refptr<GLContext> CreateGLContext(
+      GLContext* shared_context,
+      GLSurface* compatible_surface);
 
   static bool LosesAllContextsOnContextLost();
 
+ protected:
+  virtual ~GLContext();
+
  private:
+  friend class base::RefCounted<GLContext>;
   DISALLOW_COPY_AND_ASSIGN(GLContext);
 };
 
diff --git a/ui/gfx/gl/gl_context_linux.cc b/ui/gfx/gl/gl_context_linux.cc
index b68ed183..8cf2eeb 100644
--- a/ui/gfx/gl/gl_context_linux.cc
+++ b/ui/gfx/gl/gl_context_linux.cc
@@ -20,29 +20,30 @@
 
 namespace gfx {
 
-GLContext* GLContext::CreateGLContext(GLContext* shared_context,
-                                      GLSurface* compatible_surface) {
+scoped_refptr<GLContext> GLContext::CreateGLContext(
+    GLContext* shared_context,
+    GLSurface* compatible_surface) {
   switch (GetGLImplementation()) {
     case kGLImplementationOSMesaGL: {
-      scoped_ptr<GLContextOSMesa> context(new GLContextOSMesa);
+      scoped_refptr<GLContext> context(new GLContextOSMesa);
       if (!context->Initialize(shared_context, compatible_surface))
         return NULL;
 
-      return context.release();
+      return context;
     }
     case kGLImplementationEGLGLES2: {
-      scoped_ptr<GLContextEGL> context(new GLContextEGL);
+      scoped_refptr<GLContext> context(new GLContextEGL);
       if (!context->Initialize(shared_context, compatible_surface))
         return NULL;
 
-      return context.release();
+      return context;
     }
     case kGLImplementationDesktopGL: {
-      scoped_ptr<GLContextGLX> context(new GLContextGLX);
+      scoped_refptr<GLContext> context(new GLContextGLX);
       if (!context->Initialize(shared_context, compatible_surface))
         return NULL;
 
-      return context.release();
+      return context;
     }
     case kGLImplementationMockGL:
       return new GLContextStub;
diff --git a/ui/gfx/gl/gl_context_mac.cc b/ui/gfx/gl/gl_context_mac.cc
index 5627d2cae..482d93d 100644
--- a/ui/gfx/gl/gl_context_mac.cc
+++ b/ui/gfx/gl/gl_context_mac.cc
@@ -16,22 +16,23 @@
 
 namespace gfx {
 
-GLContext* GLContext::CreateGLContext(GLContext* shared_context,
-                                      GLSurface* compatible_surface) {
+scoped_refptr<GLContext> GLContext::CreateGLContext(
+    GLContext* shared_context,
+    GLSurface* compatible_surface) {
   switch (GetGLImplementation()) {
     case kGLImplementationDesktopGL: {
-      scoped_ptr<GLContextCGL> context(new GLContextCGL);
+      scoped_refptr<GLContext> context(new GLContextCGL);
       if (!context->Initialize(shared_context, compatible_surface))
         return NULL;
 
-      return context.release();
+      return context;
     }
     case kGLImplementationOSMesaGL: {
-      scoped_ptr<GLContextOSMesa> context(new GLContextOSMesa);
+      scoped_refptr<GLContext> context(new GLContextOSMesa);
       if (!context->Initialize(shared_context, compatible_surface))
         return NULL;
 
-      return context.release();
+      return context;
     }
     case kGLImplementationMockGL:
       return new GLContextStub;
diff --git a/ui/gfx/gl/gl_context_win.cc b/ui/gfx/gl/gl_context_win.cc
index 90bca79..c9f90706 100644
--- a/ui/gfx/gl/gl_context_win.cc
+++ b/ui/gfx/gl/gl_context_win.cc
@@ -20,29 +20,30 @@
 
 namespace gfx {
 
-GLContext* GLContext::CreateGLContext(GLContext* shared_context,
-                                      GLSurface* compatible_surface) {
+scoped_refptr<GLContext> GLContext::CreateGLContext(
+    GLContext* shared_context,
+    GLSurface* compatible_surface) {
   switch (GetGLImplementation()) {
     case kGLImplementationOSMesaGL: {
-      scoped_ptr<GLContextOSMesa> context(new GLContextOSMesa);
+      scoped_refptr<GLContext> context(new GLContextOSMesa);
       if (!context->Initialize(shared_context, compatible_surface))
         return NULL;
 
-      return context.release();
+      return context;
     }
     case kGLImplementationEGLGLES2: {
-      scoped_ptr<GLContextEGL> context(new GLContextEGL);
+      scoped_refptr<GLContext> context(new GLContextEGL);
       if (!context->Initialize(shared_context, compatible_surface))
         return NULL;
 
-      return context.release();
+      return context;
     }
     case kGLImplementationDesktopGL: {
-      scoped_ptr<GLContextWGL> context(new GLContextWGL);
+      scoped_refptr<GLContext> context(new GLContextWGL);
       if (!context->Initialize(shared_context, compatible_surface))
         return NULL;
 
-      return context.release();
+      return context;
     }
     case kGLImplementationMockGL:
       return new GLContextStub;
diff --git a/ui/gfx/gl/gl_interface.h b/ui/gfx/gl/gl_interface.h
index bbd2b63..5422186 100644
--- a/ui/gfx/gl/gl_interface.h
+++ b/ui/gfx/gl/gl_interface.h
@@ -427,6 +427,8 @@
 
   virtual void GetFenceivNV(GLuint fence, GLenum pname, GLint *params) = 0;
 
+  virtual void SetSurfaceCHROMIUM(GLuint id) = 0;
+
  private:
   static GLInterface* interface_;
 };
diff --git a/ui/gfx/gl/gl_surface.h b/ui/gfx/gl/gl_surface.h
index 9c1dcc4..513f37d4 100644
--- a/ui/gfx/gl/gl_surface.h
+++ b/ui/gfx/gl/gl_surface.h
@@ -6,6 +6,7 @@
 #define UI_GFX_GL_GL_SURFACE_H_
 #pragma once
 
+#include "base/memory/ref_counted.h"
 #include "build/build_config.h"
 #include "ui/gfx/native_widget_types.h"
 #include "ui/gfx/size.h"
@@ -14,10 +15,9 @@
 
 // Encapsulates a surface that can be rendered to with GL, hiding platform
 // specific management.
-class GLSurface {
+class GLSurface : public base::RefCounted<GLSurface> {
  public:
   GLSurface();
-  virtual ~GLSurface();
 
   // (Re)create the surface. TODO(apatrick): This is an ugly hack to allow the
   // EGL surface associated to be recreated without destroying the associated
@@ -49,13 +49,19 @@
 
 #if !defined(OS_MACOSX)
   // Create a GL surface that renders directly to a view.
-  static GLSurface* CreateViewGLSurface(gfx::PluginWindowHandle window);
+  static scoped_refptr<GLSurface> CreateViewGLSurface(
+      gfx::PluginWindowHandle window);
 #endif
 
   // Create a GL surface used for offscreen rendering.
-  static GLSurface* CreateOffscreenGLSurface(const gfx::Size& size);
+  static scoped_refptr<GLSurface> CreateOffscreenGLSurface(
+      const gfx::Size& size);
+
+ protected:
+  virtual ~GLSurface();
 
  private:
+  friend class base::RefCounted<GLSurface>;
   DISALLOW_COPY_AND_ASSIGN(GLSurface);
 };
 
diff --git a/ui/gfx/gl/gl_surface_linux.cc b/ui/gfx/gl/gl_surface_linux.cc
index 26c1631e9..fe96989 100644
--- a/ui/gfx/gl/gl_surface_linux.cc
+++ b/ui/gfx/gl/gl_surface_linux.cc
@@ -243,31 +243,32 @@
   return true;
 }
 
-GLSurface* GLSurface::CreateViewGLSurface(gfx::PluginWindowHandle window) {
+scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface(
+    gfx::PluginWindowHandle window) {
   switch (GetGLImplementation()) {
     case kGLImplementationOSMesaGL: {
-      scoped_ptr<NativeViewGLSurfaceOSMesa> surface(
+      scoped_refptr<GLSurface> surface(
           new NativeViewGLSurfaceOSMesa(window));
       if (!surface->Initialize())
         return NULL;
 
-      return surface.release();
+      return surface;
     }
     case kGLImplementationEGLGLES2: {
-      scoped_ptr<NativeViewGLSurfaceEGL> surface(new NativeViewGLSurfaceEGL(
+      scoped_refptr<GLSurface> surface(new NativeViewGLSurfaceEGL(
           window));
       if (!surface->Initialize())
         return NULL;
 
-      return surface.release();
+      return surface;
     }
     case kGLImplementationDesktopGL: {
-      scoped_ptr<NativeViewGLSurfaceGLX> surface(new NativeViewGLSurfaceGLX(
+      scoped_refptr<GLSurface> surface(new NativeViewGLSurfaceGLX(
           window));
       if (!surface->Initialize())
         return NULL;
 
-      return surface.release();
+      return surface;
     }
     case kGLImplementationMockGL:
       return new GLSurfaceStub;
@@ -277,29 +278,30 @@
   }
 }
 
-GLSurface* GLSurface::CreateOffscreenGLSurface(const gfx::Size& size) {
+scoped_refptr<GLSurface> GLSurface::CreateOffscreenGLSurface(
+    const gfx::Size& size) {
   switch (GetGLImplementation()) {
     case kGLImplementationOSMesaGL: {
-      scoped_ptr<GLSurfaceOSMesa> surface(new GLSurfaceOSMesa(OSMESA_RGBA,
-                                                              size));
+      scoped_refptr<GLSurface> surface(new GLSurfaceOSMesa(OSMESA_RGBA,
+                                                           size));
       if (!surface->Initialize())
         return NULL;
 
-      return surface.release();
+      return surface;
     }
     case kGLImplementationEGLGLES2: {
-      scoped_ptr<PbufferGLSurfaceEGL> surface(new PbufferGLSurfaceEGL(size));
+      scoped_refptr<GLSurface> surface(new PbufferGLSurfaceEGL(size));
       if (!surface->Initialize())
         return NULL;
 
-      return surface.release();
+      return surface;
     }
     case kGLImplementationDesktopGL: {
-      scoped_ptr<PbufferGLSurfaceGLX> surface(new PbufferGLSurfaceGLX(size));
+      scoped_refptr<GLSurface> surface(new PbufferGLSurfaceGLX(size));
       if (!surface->Initialize())
         return NULL;
 
-      return surface.release();
+      return surface;
     }
     case kGLImplementationMockGL:
       return new GLSurfaceStub;
diff --git a/ui/gfx/gl/gl_surface_mac.cc b/ui/gfx/gl/gl_surface_mac.cc
index bb08ef8..2367679b 100644
--- a/ui/gfx/gl/gl_surface_mac.cc
+++ b/ui/gfx/gl/gl_surface_mac.cc
@@ -50,23 +50,24 @@
 
 // TODO(apatrick): support ViewGLSurface on mac.
 #if 0
-GLSurface* GLSurface::CreateViewGLSurface(gfx::PluginWindowHandle window) {
+scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface(
+    gfx::PluginWindowHandle window) {
   switch (GetGLImplementation()) {
     case kGLImplementationOSMesaGL: {
-      scoped_ptr<NativeViewGLSurfaceOSMesa> surface(
+      scoped_refptr<GLSurface> surface(
           new NativeViewGLSurfaceOSMesa(window));
       if (!surface->Initialize())
         return NULL;
 
-      return surface.release();
+      return surface;
     }
     case kGLImplementationDesktopGL: {
-      scoped_ptr<NativeViewGLSurfaceCGL> surface(new NativeViewGLSurfaceCGL(
+      scoped_refptr<GLSurface> surface(new NativeViewGLSurfaceCGL(
           window));
       if (!surface->Initialize())
         return NULL;
 
-      return surface.release();
+      return surface;
     }
     case kGLImplementationMockGL:
       return new GLSurfaceStub;
@@ -77,22 +78,23 @@
 }
 #endif
 
-GLSurface* GLSurface::CreateOffscreenGLSurface(const gfx::Size& size) {
+scoped_refptr<GLSurface> GLSurface::CreateOffscreenGLSurface(
+    const gfx::Size& size) {
   switch (GetGLImplementation()) {
     case kGLImplementationOSMesaGL: {
-      scoped_ptr<GLSurfaceOSMesa> surface(new GLSurfaceOSMesa(OSMESA_RGBA,
-                                                              size));
+      scoped_refptr<GLSurface> surface(new GLSurfaceOSMesa(OSMESA_RGBA,
+                                                           size));
       if (!surface->Initialize())
         return NULL;
 
-      return surface.release();
+      return surface;
     }
     case kGLImplementationDesktopGL: {
-      scoped_ptr<PbufferGLSurfaceCGL> surface(new PbufferGLSurfaceCGL(size));
+      scoped_refptr<GLSurface> surface(new PbufferGLSurfaceCGL(size));
       if (!surface->Initialize())
         return NULL;
 
-      return surface.release();
+      return surface;
     }
     case kGLImplementationMockGL:
       return new GLSurfaceStub;
diff --git a/ui/gfx/gl/gl_surface_win.cc b/ui/gfx/gl/gl_surface_win.cc
index 594a263..6b3ea8c 100644
--- a/ui/gfx/gl/gl_surface_win.cc
+++ b/ui/gfx/gl/gl_surface_win.cc
@@ -167,31 +167,32 @@
   Resize(window_size);
 }
 
-GLSurface* GLSurface::CreateViewGLSurface(gfx::PluginWindowHandle window) {
+scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface(
+    gfx::PluginWindowHandle window) {
   switch (GetGLImplementation()) {
     case kGLImplementationOSMesaGL: {
-      scoped_ptr<NativeViewGLSurfaceOSMesa> surface(
+      scoped_refptr<GLSurface> surface(
           new NativeViewGLSurfaceOSMesa(window));
       if (!surface->Initialize())
         return NULL;
 
-      return surface.release();
+      return surface;
     }
     case kGLImplementationEGLGLES2: {
-      scoped_ptr<NativeViewGLSurfaceEGL> surface(new NativeViewGLSurfaceEGL(
+      scoped_refptr<GLSurface> surface(new NativeViewGLSurfaceEGL(
           window));
       if (!surface->Initialize())
         return NULL;
 
-      return surface.release();
+      return surface;
     }
     case kGLImplementationDesktopGL: {
-      scoped_ptr<NativeViewGLSurfaceWGL> surface(new NativeViewGLSurfaceWGL(
+      scoped_refptr<GLSurface> surface(new NativeViewGLSurfaceWGL(
           window));
       if (!surface->Initialize())
         return NULL;
 
-      return surface.release();
+      return surface;
     }
     case kGLImplementationMockGL:
       return new GLSurfaceStub;
@@ -201,29 +202,30 @@
   }
 }
 
-GLSurface* GLSurface::CreateOffscreenGLSurface(const gfx::Size& size) {
+scoped_refptr<GLSurface> GLSurface::CreateOffscreenGLSurface(
+    const gfx::Size& size) {
   switch (GetGLImplementation()) {
     case kGLImplementationOSMesaGL: {
-      scoped_ptr<GLSurfaceOSMesa> surface(new GLSurfaceOSMesa(OSMESA_RGBA,
-                                                              size));
+      scoped_refptr<GLSurface> surface(new GLSurfaceOSMesa(OSMESA_RGBA,
+                                                           size));
       if (!surface->Initialize())
         return NULL;
 
-      return surface.release();
+      return surface;
     }
     case kGLImplementationEGLGLES2: {
-      scoped_ptr<PbufferGLSurfaceEGL> surface(new PbufferGLSurfaceEGL(size));
+      scoped_refptr<GLSurface> surface(new PbufferGLSurfaceEGL(size));
       if (!surface->Initialize())
         return NULL;
 
-      return surface.release();
+      return surface;
     }
     case kGLImplementationDesktopGL: {
-      scoped_ptr<PbufferGLSurfaceWGL> surface(new PbufferGLSurfaceWGL(size));
+      scoped_refptr<GLSurface> surface(new PbufferGLSurfaceWGL(size));
       if (!surface->Initialize())
         return NULL;
 
-      return surface.release();
+      return surface;
     }
     case kGLImplementationMockGL:
       return new GLSurfaceStub;
diff --git a/ui/gfx/surface/accelerated_surface_mac.cc b/ui/gfx/surface/accelerated_surface_mac.cc
index a749c46..ce2f7a0 100644
--- a/ui/gfx/surface/accelerated_surface_mac.cc
+++ b/ui/gfx/surface/accelerated_surface_mac.cc
@@ -35,14 +35,14 @@
   if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL)
     return false;
 
-  gl_surface_.reset(gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1)));
+  gl_surface_ = gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1));
   if (!gl_surface_.get()) {
     Destroy();
     return false;
   }
 
-  gl_context_.reset(gfx::GLContext::CreateGLContext(share_context,
-                                                    gl_surface_.get()));
+  gl_context_ = gfx::GLContext::CreateGLContext(share_context,
+                                                gl_surface_.get());
   if (!gl_context_.get()) {
     Destroy();
     return false;
@@ -66,8 +66,8 @@
   }
   transport_dib_.reset();
 
-  gl_context_.reset();
-  gl_surface_.reset();
+  gl_context_ = NULL;
+  gl_surface_ = NULL;
 }
 
 // Call after making changes to the surface which require a visual update.
diff --git a/ui/gfx/surface/accelerated_surface_mac.h b/ui/gfx/surface/accelerated_surface_mac.h
index 13bec9b..d9ee833 100644
--- a/ui/gfx/surface/accelerated_surface_mac.h
+++ b/ui/gfx/surface/accelerated_surface_mac.h
@@ -129,8 +129,8 @@
   // speaking, we do not need to allocate a GL context all of the
   // time. We only need one if (a) we are using the IOSurface code
   // path, or (b) if we are allocating an FBO internally.
-  scoped_ptr<gfx::GLSurface> gl_surface_;
-  scoped_ptr<gfx::GLContext> gl_context_;
+  scoped_refptr<gfx::GLSurface> gl_surface_;
+  scoped_refptr<gfx::GLContext> gl_context_;
   // Either |io_surface_| or |transport_dib_| is a valid pointer, but not both.
   // |io_surface_| is non-NULL if the IOSurface APIs are supported (Mac OS X
   // 10.6 and later).
diff --git a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc
index 62439d8..dfb4959 100644
--- a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc
+++ b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc
@@ -10,6 +10,7 @@
 #include <string>
 
 #include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
@@ -133,7 +134,7 @@
   // and from there to the window, and WebViewImpl::paint already
   // correctly handles the case where the compositor is active but
   // the output needs to go to a WebCanvas.
-  gl_surface_.reset(gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1)));
+  gl_surface_ = gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1));
 
   if (!gl_surface_.get()) {
     if (!is_gles2_)
@@ -148,14 +149,13 @@
     // necessary.
     webView->mainFrame()->collectGarbage();
 
-    gl_surface_.reset(gfx::GLSurface::CreateOffscreenGLSurface(
-        gfx::Size(1, 1)));
+    gl_surface_ = gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1));
     if (!gl_surface_.get())
       return false;
   }
 
-  gl_context_.reset(gfx::GLContext::CreateGLContext(share_context,
-                                                    gl_surface_.get()));
+  gl_context_ = gfx::GLContext::CreateGLContext(share_context,
+                                                gl_surface_.get());
   if (!gl_context_.get()) {
     if (!is_gles2_)
       return false;
@@ -169,8 +169,8 @@
     // necessary.
     webView->mainFrame()->collectGarbage();
 
-    gl_context_.reset(gfx::GLContext::CreateGLContext(share_context,
-                                                      gl_surface_.get()));
+    gl_context_ = gfx::GLContext::CreateGLContext(share_context,
+                                                  gl_surface_.get());
     if (!gl_context_.get())
       return false;
   }
@@ -189,7 +189,7 @@
     attributes_.antialias = false;
 
   if (!gl_context_->MakeCurrent(gl_surface_.get())) {
-    gl_context_.reset();
+    gl_context_ = NULL;
     return false;
   }
 
diff --git a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h
index 08c8df19..dc51c80 100644
--- a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h
+++ b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h
@@ -9,7 +9,7 @@
 #include <set>
 
 #include "base/hash_tables.h"
-#include "base/memory/scoped_ptr.h"
+#include "base/memory/ref_counted.h"
 #include "third_party/angle/include/GLSLANG/ShaderLang.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebGraphicsContext3D.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
@@ -464,8 +464,8 @@
   std::list<WGC3Denum> synthetic_errors_list_;
   std::set<WGC3Denum> synthetic_errors_set_;
 
-  scoped_ptr<gfx::GLContext> gl_context_;
-  scoped_ptr<gfx::GLSurface> gl_surface_;
+  scoped_refptr<gfx::GLContext> gl_context_;
+  scoped_refptr<gfx::GLSurface> gl_surface_;
 
   ShaderSourceMap shader_source_map_;
 
diff --git a/webkit/gpu/webgraphicscontext3d_in_process_impl.cc b/webkit/gpu/webgraphicscontext3d_in_process_impl.cc
index f2fc2e9..f79f4a6 100644
--- a/webkit/gpu/webgraphicscontext3d_in_process_impl.cc
+++ b/webkit/gpu/webgraphicscontext3d_in_process_impl.cc
@@ -10,6 +10,7 @@
 #include <string>
 
 #include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
@@ -134,8 +135,7 @@
   // and from there to the window, and WebViewImpl::paint already
   // correctly handles the case where the compositor is active but
   // the output needs to go to a WebCanvas.
-  gl_surface_.reset(gfx::GLSurface::CreateOffscreenGLSurface(
-      gfx::Size(1, 1)));
+  gl_surface_ = gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1));
   if (!gl_surface_.get()) {
     if (!is_gles2_)
       return false;
@@ -149,14 +149,13 @@
     // necessary.
     webView->mainFrame()->collectGarbage();
 
-    gl_surface_.reset(
-        gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1)));
+    gl_surface_ = gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1));
     if (!gl_surface_.get())
       return false;
   }
 
-  gl_context_.reset(gfx::GLContext::CreateGLContext(share_context,
-                                                    gl_surface_.get()));
+  gl_context_ = gfx::GLContext::CreateGLContext(share_context,
+                                                gl_surface_.get());
   if (!gl_context_.get()) {
     if (!is_gles2_)
       return false;
@@ -170,8 +169,8 @@
     // necessary.
     webView->mainFrame()->collectGarbage();
 
-    gl_context_.reset(gfx::GLContext::CreateGLContext(share_context,
-                                                      gl_surface_.get()));
+    gl_context_ = gfx::GLContext::CreateGLContext(share_context,
+                                                  gl_surface_.get());
     if (!gl_context_.get())
       return false;
   }
@@ -190,7 +189,7 @@
     attributes_.antialias = false;
 
   if (!gl_context_->MakeCurrent(gl_surface_.get())) {
-    gl_context_.reset();
+    gl_context_ = NULL;
     return false;
   }
 
diff --git a/webkit/gpu/webgraphicscontext3d_in_process_impl.h b/webkit/gpu/webgraphicscontext3d_in_process_impl.h
index ae3fac2..304f9fb 100644
--- a/webkit/gpu/webgraphicscontext3d_in_process_impl.h
+++ b/webkit/gpu/webgraphicscontext3d_in_process_impl.h
@@ -9,7 +9,7 @@
 #include <set>
 
 #include "base/hash_tables.h"
-#include "base/memory/scoped_ptr.h"
+#include "base/memory/ref_counted.h"
 #include "third_party/angle/include/GLSLANG/ShaderLang.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebGraphicsContext3D.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
@@ -468,8 +468,8 @@
   std::list<WGC3Denum> synthetic_errors_list_;
   std::set<WGC3Denum> synthetic_errors_set_;
 
-  scoped_ptr<gfx::GLContext> gl_context_;
-  scoped_ptr<gfx::GLSurface> gl_surface_;
+  scoped_refptr<gfx::GLContext> gl_context_;
+  scoped_refptr<gfx::GLSurface> gl_surface_;
 
   ShaderSourceMap shader_source_map_;