| Index: ui/gl/gl_image_io_surface.mm
|
| diff --git a/ui/gl/gl_image_io_surface.mm b/ui/gl/gl_image_io_surface.mm
|
| index 8a89afd579f1453d4f152d0b424494e9ecb825ff..e8d9592a74f115ab5411cab8db10a1bb967803e9 100644
|
| --- a/ui/gl/gl_image_io_surface.mm
|
| +++ b/ui/gl/gl_image_io_surface.mm
|
| @@ -301,6 +301,23 @@ bool GLImageIOSurface::CopyTexImage(unsigned target) {
|
| return false;
|
| }
|
|
|
| + GLint target_texture = 0;
|
| + glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &target_texture);
|
| + DCHECK(target_texture);
|
| +
|
| + // Manually re-set the state in the scoped closure runner, to avoid bugs
|
| + // in using gfx::ScopedActiveTexture and gfx::ScopedTextureBinder together.
|
| + // https://crbug.com/601729
|
| + GLint old_active_texture = -1;
|
| + glGetIntegerv(GL_ACTIVE_TEXTURE, &old_active_texture);
|
| + GLint old_texture0_binding = -1;
|
| + glActiveTexture(GL_TEXTURE0);
|
| + glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_texture0_binding);
|
| + GLint old_texture1_binding = -1;
|
| + glActiveTexture(GL_TEXTURE1);
|
| + glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_texture1_binding);
|
| + glActiveTexture(old_active_texture);
|
| +
|
| // Ensure that all textures bound to IOSurfaces be destroyed before the
|
| // function exits. If they are not destroyed they may cause deadlocks between
|
| // VTDecompressionSession at CGLContextDestroy.
|
| @@ -309,10 +326,17 @@ bool GLImageIOSurface::CopyTexImage(unsigned target) {
|
| glGenTextures(1, &y_texture);
|
| unsigned uv_texture = 0;
|
| glGenTextures(1, &uv_texture);
|
| - base::ScopedClosureRunner destroy_resources_runner(base::BindBlock(^{
|
| - glDeleteTextures(1, &y_texture);
|
| - glDeleteTextures(1, &uv_texture);
|
| - }));
|
| + base::ScopedClosureRunner restore_bindings_and_destroy_resources(
|
| + base::BindBlock(^{
|
| + glActiveTexture(GL_TEXTURE0);
|
| + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, old_texture0_binding);
|
| + glActiveTexture(GL_TEXTURE1);
|
| + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, old_texture1_binding);
|
| + glActiveTexture(old_active_texture);
|
| +
|
| + glDeleteTextures(1, &y_texture);
|
| + glDeleteTextures(1, &uv_texture);
|
| + }));
|
|
|
| if (!framebuffer_) {
|
| glGenFramebuffersEXT(1, &framebuffer_);
|
| @@ -342,19 +366,14 @@ bool GLImageIOSurface::CopyTexImage(unsigned target) {
|
| CGLContextObj cgl_context =
|
| static_cast<CGLContextObj>(gfx::GLContext::GetCurrent()->GetHandle());
|
|
|
| - GLint target_texture = 0;
|
| - glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &target_texture);
|
| - DCHECK(target_texture);
|
| glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, size_.width(),
|
| size_.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
|
|
|
| CGLError cgl_error = kCGLNoError;
|
| - {
|
| DCHECK(io_surface_);
|
|
|
| - gfx::ScopedActiveTexture active_texture0(GL_TEXTURE0);
|
| - gfx::ScopedTextureBinder texture_y_binder(GL_TEXTURE_RECTANGLE_ARB,
|
| - y_texture);
|
| + glActiveTexture(GL_TEXTURE0);
|
| + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, y_texture);
|
| cgl_error = CGLTexImageIOSurface2D(
|
| cgl_context, GL_TEXTURE_RECTANGLE_ARB, GL_RED, size_.width(),
|
| size_.height(), GL_RED, GL_UNSIGNED_BYTE, io_surface_.get(), 0);
|
| @@ -363,36 +382,33 @@ bool GLImageIOSurface::CopyTexImage(unsigned target) {
|
| << cgl_error;
|
| return false;
|
| }
|
| - {
|
| - gfx::ScopedActiveTexture active_texture1(GL_TEXTURE1);
|
| - gfx::ScopedTextureBinder texture_uv_binder(GL_TEXTURE_RECTANGLE_ARB,
|
| - uv_texture);
|
| - cgl_error = CGLTexImageIOSurface2D(
|
| - cgl_context, GL_TEXTURE_RECTANGLE_ARB, GL_RG, size_.width() / 2,
|
| - size_.height() / 2, GL_RG, GL_UNSIGNED_BYTE, io_surface_.get(), 1);
|
| - if (cgl_error != kCGLNoError) {
|
| - LOG(ERROR) << "Error in CGLTexImageIOSurface2D for the UV plane. "
|
| - << cgl_error;
|
| - return false;
|
| - }
|
| -
|
| - gfx::ScopedFrameBufferBinder framebuffer_binder(framebuffer_);
|
| - gfx::ScopedViewport viewport(0, 0, size_.width(), size_.height());
|
| - glViewport(0, 0, size_.width(), size_.height());
|
| - glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
| - GL_TEXTURE_RECTANGLE_ARB, target_texture, 0);
|
| - DCHECK_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
|
| - glCheckFramebufferStatusEXT(GL_FRAMEBUFFER));
|
| -
|
| - gfx::ScopedUseProgram use_program(program_);
|
| - glUniform2f(size_location_, size_.width(), size_.height());
|
| -
|
| - gfx::GLHelper::DrawQuad(vertex_buffer_);
|
| - // Detach the output texture from the fbo.
|
| - glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
| - GL_TEXTURE_RECTANGLE_ARB, 0, 0);
|
| - }
|
| +
|
| + glActiveTexture(GL_TEXTURE1);
|
| + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, uv_texture);
|
| + cgl_error = CGLTexImageIOSurface2D(
|
| + cgl_context, GL_TEXTURE_RECTANGLE_ARB, GL_RG, size_.width() / 2,
|
| + size_.height() / 2, GL_RG, GL_UNSIGNED_BYTE, io_surface_.get(), 1);
|
| + if (cgl_error != kCGLNoError) {
|
| + LOG(ERROR) << "Error in CGLTexImageIOSurface2D for the UV plane. "
|
| + << cgl_error;
|
| + return false;
|
| }
|
| +
|
| + gfx::ScopedFrameBufferBinder framebuffer_binder(framebuffer_);
|
| + gfx::ScopedViewport viewport(0, 0, size_.width(), size_.height());
|
| + glViewport(0, 0, size_.width(), size_.height());
|
| + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
| + GL_TEXTURE_RECTANGLE_ARB, target_texture, 0);
|
| + DCHECK_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
|
| + glCheckFramebufferStatusEXT(GL_FRAMEBUFFER));
|
| +
|
| + gfx::ScopedUseProgram use_program(program_);
|
| + glUniform2f(size_location_, size_.width(), size_.height());
|
| +
|
| + gfx::GLHelper::DrawQuad(vertex_buffer_);
|
| + // Detach the output texture from the fbo.
|
| + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
| + GL_TEXTURE_RECTANGLE_ARB, 0, 0);
|
| return true;
|
| }
|
|
|
|
|