| Index: content/common/gpu/image_transport_surface_mac.cc | 
| diff --git a/content/common/gpu/image_transport_surface_mac.cc b/content/common/gpu/image_transport_surface_mac.cc | 
| index 6dc3149d9a6da8062e5c2e3a0aaad064f03a78cc..ed9a4aa81e83fd00f4e106cedfc58bc434990df5 100644 | 
| --- a/content/common/gpu/image_transport_surface_mac.cc | 
| +++ b/content/common/gpu/image_transport_surface_mac.cc | 
| @@ -37,6 +37,7 @@ class IOSurfaceImageTransportSurface : public gfx::NoOpGLSurfaceCGL, | 
| virtual gfx::Size GetSize() OVERRIDE; | 
| virtual bool OnMakeCurrent(gfx::GLContext* context) OVERRIDE; | 
| virtual unsigned int GetBackingFrameBufferObject() OVERRIDE; | 
| +  virtual void SetBufferAllocation(BufferAllocationState state) OVERRIDE; | 
|  | 
| protected: | 
| // ImageTransportSurface implementation | 
| @@ -50,6 +51,11 @@ class IOSurfaceImageTransportSurface : public gfx::NoOpGLSurfaceCGL, | 
| private: | 
| virtual ~IOSurfaceImageTransportSurface() OVERRIDE; | 
|  | 
| +  void UnrefIOSurface(); | 
| +  void CreateIOSurface(); | 
| + | 
| +  BufferAllocationState buffer_allocation_state_; | 
| + | 
| uint32 fbo_id_; | 
| GLuint texture_id_; | 
|  | 
| @@ -91,6 +97,7 @@ IOSurfaceImageTransportSurface::IOSurfaceImageTransportSurface( | 
| GpuCommandBufferStub* stub, | 
| gfx::PluginWindowHandle handle) | 
| : gfx::NoOpGLSurfaceCGL(gfx::Size(1, 1)), | 
| +      buffer_allocation_state_(BUFFER_ALLOCATION_FRONT_AND_BACK), | 
| fbo_id_(0), | 
| texture_id_(0), | 
| io_surface_handle_(0), | 
| @@ -141,16 +148,8 @@ bool IOSurfaceImageTransportSurface::OnMakeCurrent(gfx::GLContext* context) { | 
| if (made_current_) | 
| return true; | 
|  | 
| -  glGenFramebuffersEXT(1, &fbo_id_); | 
| -  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id_); | 
| OnResize(gfx::Size(1, 1)); | 
|  | 
| -  GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); | 
| -  if (status != GL_FRAMEBUFFER_COMPLETE) { | 
| -    DLOG(ERROR) << "Framebuffer incomplete."; | 
| -    return false; | 
| -  } | 
| - | 
| made_current_ = true; | 
| return true; | 
| } | 
| @@ -159,6 +158,30 @@ unsigned int IOSurfaceImageTransportSurface::GetBackingFrameBufferObject() { | 
| return fbo_id_; | 
| } | 
|  | 
| +void IOSurfaceImageTransportSurface::SetBufferAllocation( | 
| +    BufferAllocationState state) { | 
| +  if (buffer_allocation_state_ == state) | 
| +    return; | 
| +  buffer_allocation_state_ = state; | 
| + | 
| +  switch (state) { | 
| +    case BUFFER_ALLOCATION_FRONT_AND_BACK: | 
| +      CreateIOSurface(); | 
| +      break; | 
| + | 
| +    case BUFFER_ALLOCATION_FRONT_ONLY: | 
| +      break; | 
| + | 
| +    case BUFFER_ALLOCATION_NONE: | 
| +      UnrefIOSurface(); | 
| +      helper_->Suspend(); | 
| +      break; | 
| + | 
| +    default: | 
| +      NOTREACHED(); | 
| +  } | 
| +} | 
| + | 
| bool IOSurfaceImageTransportSurface::SwapBuffers() { | 
| glFlush(); | 
|  | 
| @@ -217,23 +240,44 @@ void IOSurfaceImageTransportSurface::OnResizeViewACK() { | 
| } | 
|  | 
| void IOSurfaceImageTransportSurface::OnResize(gfx::Size size) { | 
| -  IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize(); | 
| - | 
| // Caching |context_| from OnMakeCurrent. It should still be current. | 
| DCHECK(context_->IsCurrent(this)); | 
|  | 
| size_ = size; | 
|  | 
| +  CreateIOSurface(); | 
| +} | 
| + | 
| +void IOSurfaceImageTransportSurface::UnrefIOSurface() { | 
| +  DCHECK(context_->IsCurrent(this)); | 
| + | 
| +  if (fbo_id_) { | 
| +    glDeleteFramebuffersEXT(1, &fbo_id_); | 
| +    fbo_id_ = 0; | 
| +  } | 
| + | 
| if (texture_id_) { | 
| glDeleteTextures(1, &texture_id_); | 
| texture_id_ = 0; | 
| } | 
|  | 
| -  glGenTextures(1, &texture_id_); | 
| +  io_surface_.reset(); | 
| +  io_surface_handle_ = 0; | 
| +} | 
|  | 
| +void IOSurfaceImageTransportSurface::CreateIOSurface() { | 
| GLint previous_texture_id = 0; | 
| glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &previous_texture_id); | 
|  | 
| +  UnrefIOSurface(); | 
| + | 
| +  glGenFramebuffersEXT(1, &fbo_id_); | 
| +  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id_); | 
| + | 
| +  IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize(); | 
| + | 
| +  glGenTextures(1, &texture_id_); | 
| + | 
| // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on | 
| // Mac OS X and is required for IOSurface interoperability. | 
| GLenum target = GL_TEXTURE_RECTANGLE_ARB; | 
| @@ -243,11 +287,6 @@ void IOSurfaceImageTransportSurface::OnResize(gfx::Size size) { | 
| glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 
| glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 
|  | 
| -  GLint previous_fbo_id = 0; | 
| -  glGetIntegerv(GL_FRAMEBUFFER_BINDING, &previous_fbo_id); | 
| - | 
| -  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id_); | 
| - | 
| glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, | 
| GL_COLOR_ATTACHMENT0_EXT, | 
| target, | 
| @@ -278,22 +317,28 @@ void IOSurfaceImageTransportSurface::OnResize(gfx::Size size) { | 
|  | 
| // Don't think we need to identify a plane. | 
| GLuint plane = 0; | 
| -  io_surface_support->CGLTexImageIOSurface2D( | 
| -      static_cast<CGLContextObj>(context_->GetHandle()), | 
| -      target, | 
| -      GL_RGBA, | 
| -      size_.width(), | 
| -      size_.height(), | 
| -      GL_BGRA, | 
| -      GL_UNSIGNED_INT_8_8_8_8_REV, | 
| -      io_surface_.get(), | 
| -      plane); | 
| +  CGLError cglerror = | 
| +      io_surface_support->CGLTexImageIOSurface2D( | 
| +          static_cast<CGLContextObj>(context_->GetHandle()), | 
| +          target, | 
| +          GL_RGBA, | 
| +          size_.width(), | 
| +          size_.height(), | 
| +          GL_BGRA, | 
| +          GL_UNSIGNED_INT_8_8_8_8_REV, | 
| +          io_surface_.get(), | 
| +          plane); | 
| +  if (cglerror != kCGLNoError) { | 
| +    DLOG(ERROR) << "CGLTexImageIOSurface2D: " << cglerror; | 
| +    UnrefIOSurface(); | 
| +    return; | 
| +  } | 
|  | 
| io_surface_handle_ = io_surface_support->IOSurfaceGetID(io_surface_); | 
| glFlush(); | 
|  | 
| glBindTexture(target, previous_texture_id); | 
| -  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, previous_fbo_id); | 
| +  // The FBO remains bound for this GL context. | 
| } | 
|  | 
| }  // namespace | 
|  |