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 |