Chromium Code Reviews| Index: content/common/gpu/gpu_memory_buffer_factory_surface_texture.cc |
| diff --git a/content/common/gpu/gpu_memory_buffer_factory_surface_texture.cc b/content/common/gpu/gpu_memory_buffer_factory_surface_texture.cc |
| index a4cf15ed30ede039e8bc3e14ba3cd46f1a8a9359..ac79ef93e7d11dae10d0f7e625ea471c77cf255b 100644 |
| --- a/content/common/gpu/gpu_memory_buffer_factory_surface_texture.cc |
| +++ b/content/common/gpu/gpu_memory_buffer_factory_surface_texture.cc |
| @@ -6,7 +6,9 @@ |
| #include "content/common/android/surface_texture_manager.h" |
| #include "ui/gl/android/surface_texture.h" |
| +#include "ui/gl/gl_bindings.h" |
| #include "ui/gl/gl_image_surface_texture.h" |
| +#include "ui/gl/scoped_binders.h" |
| namespace content { |
| @@ -23,8 +25,8 @@ bool GpuMemoryBufferFactorySurfaceTexture:: |
| switch (usage) { |
| case gfx::BufferUsage::GPU_READ: |
| case gfx::BufferUsage::SCANOUT: |
| - case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT: |
| return false; |
| + case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT: |
| case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE: |
| return format == gfx::BufferFormat::RGBA_8888; |
| } |
| @@ -40,13 +42,14 @@ GpuMemoryBufferFactorySurfaceTexture::CreateGpuMemoryBuffer( |
| gfx::BufferUsage usage, |
| int client_id, |
| gfx::PluginWindowHandle surface_handle) { |
| - // Note: this needs to be 0 as the surface texture implemenation will take |
| - // ownership of the texture and call glDeleteTextures when the GPU service |
| - // attaches the surface texture to a real texture id. glDeleteTextures |
| - // silently ignores 0. |
| + // This can be called on a thread without a GL context current so use a dummy |
| + // texture id instread of a real one. |
|
Daniele Castagna
2015/12/05 23:43:56
instread!
reveman
2015/12/05 23:54:07
Done
|
| + // Note: This needs to be 0 as the surface texture implemenation will take |
| + // ownership of the texture and call glDeleteTextures when we attach a real |
| + // texture id to it. See CreateImageForGpuMemoryBuffer() below. |
| const int kDummyTextureId = 0; |
| scoped_refptr<gfx::SurfaceTexture> surface_texture = |
| - gfx::SurfaceTexture::Create(kDummyTextureId); |
| + gfx::SurfaceTexture::CreateSingleBuffered(kDummyTextureId); |
| if (!surface_texture.get()) |
| return gfx::GpuMemoryBufferHandle(); |
| @@ -111,12 +114,34 @@ GpuMemoryBufferFactorySurfaceTexture::CreateImageForGpuMemoryBuffer( |
| SurfaceTextureMapKey key(handle.id.id, client_id); |
| SurfaceTextureMap::iterator it = surface_textures_.find(key); |
| if (it == surface_textures_.end()) |
| - return scoped_refptr<gl::GLImage>(); |
| + return nullptr; |
| + |
| + gfx::SurfaceTexture* surface_texture = it->second.get(); |
| + // Note: Surface textures used as gpu memory buffers are created with an |
| + // initial dummy texture id of 0. We need to call DetachFromGLContext() here |
| + // to detach from the dummy texture before we can attach to a real texture |
| + // id. DetachFromGLContext() will delete the texture for the current |
| + // attachment point. Detaching from the dummy texture id should not cause any |
| + // problems as the GL should silently ignore 0 when passed to |
| + // glDeleteTextures. |
| + surface_texture->DetachFromGLContext(); |
| + |
| + // Create a real texture. |
| + GLuint texture_id = 0; |
| + glGenTextures(1, &texture_id); |
| + DCHECK(texture_id); |
| + { |
| + gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_EXTERNAL_OES, |
| + texture_id); |
| + // This will attach the surface texture to the texture currently bound to |
| + // GL_TEXTURE_EXTERNAL_OES target and take ownership of the texture. |
| + surface_texture->AttachToGLContext(); |
| + } |
| scoped_refptr<gl::GLImageSurfaceTexture> image( |
| new gl::GLImageSurfaceTexture(size)); |
| - if (!image->Initialize(it->second.get())) |
| - return scoped_refptr<gl::GLImage>(); |
| + if (!image->Initialize(surface_texture)) |
| + return nullptr; |
| return image; |
| } |