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; |
} |