| 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.
|
| + // 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;
|
| }
|
|
|