Chromium Code Reviews| Index: gpu/command_buffer/service/gles2_cmd_decoder.cc |
| diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| index 31f6a8b5731d205700703d22fbae56370061b686..a6263f451f10bd9457feb8e346328ebdbab855de 100644 |
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| @@ -49,8 +49,14 @@ |
| #include "gpu/command_buffer/service/texture_manager.h" |
| #include "gpu/command_buffer/service/vertex_attrib_manager.h" |
| #include "ui/gl/gl_context.h" |
| +#if defined(USE_X11) |
| +#include "ui/gl/gl_context_glx.h" |
| +#endif |
| #include "ui/gl/gl_implementation.h" |
| #include "ui/gl/gl_surface.h" |
| +#if defined(USE_X11) |
| +#include "ui/gl/gl_surface_glx.h" |
| +#endif |
| #if defined(OS_MACOSX) |
| #include "ui/surface/io_surface_support_mac.h" |
| #endif |
| @@ -757,6 +763,11 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, |
| GLsizei width, |
| GLsizei height); |
| + // Wrapper for TexImagePixmap2DCHROMIUM. |
| + void DoTexImagePixmap2DCHROMIUM( |
| + GLenum target, |
| + GLuint pixmap_id); |
| + |
| void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key); |
| void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key); |
| @@ -1325,6 +1336,10 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, |
| void ReleaseIOSurfaceForTexture(GLuint texture_id); |
| #endif |
| +#if defined(USE_X11) |
| + void ReleaseGLXPixmapForTexture(GLuint texture_id); |
| +#endif |
| + |
| // Validates the combination of texture parameters. For example validates that |
| // for a given format the specific type, level and targets are valid. |
| // Synthesizes the correct GL error if invalid. Returns true if valid. |
| @@ -1549,6 +1564,12 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, |
| TextureToIOSurfaceMap texture_to_io_surface_map_; |
| #endif |
| +#if defined(USE_X11) |
| + typedef std::map< |
| + GLuint, scoped_refptr<gfx::GLSurface> > TextureToPixmapGLSurfaceMap; |
| + TextureToPixmapGLSurfaceMap texture_to_pixmap_gl_surface_map_; |
|
greggman
2012/06/13 00:15:51
What happens if I use this texture from another co
|
| +#endif |
| + |
| typedef std::vector<GLES2DecoderImpl*> ChildList; |
| ChildList children_; |
| @@ -2508,6 +2529,9 @@ void GLES2DecoderImpl::DeleteTexturesHelper( |
| ReleaseIOSurfaceForTexture(service_id); |
| } |
| #endif |
| +#if defined(USE_X11) |
| + ReleaseGLXPixmapForTexture(service_id); |
| +#endif |
| RemoveTextureInfo(client_ids[ii]); |
| } |
| } |
| @@ -2858,6 +2882,19 @@ void GLES2DecoderImpl::Destroy(bool have_context) { |
| } |
| texture_to_io_surface_map_.clear(); |
| #endif |
| + |
| +#if defined(USE_X11) |
| + for (TextureToPixmapGLSurfaceMap::iterator it = |
| + texture_to_pixmap_gl_surface_map_.begin(); |
| + it != texture_to_pixmap_gl_surface_map_.end(); ++it) { |
| + scoped_refptr<gfx::GLSurface> pixmap_gl_surface = it->second; |
| + glXReleaseTexImageEXT( |
| + static_cast<gfx::GLContextGLX*>(GetGLContext())->display(), |
|
piman
2012/06/12 23:15:38
This is not a safe cast when based only on USE_X11
|
| + reinterpret_cast<GLXDrawable>(pixmap_gl_surface->GetHandle()), |
| + GLX_FRONT_LEFT_EXT); |
| + } |
| + texture_to_pixmap_gl_surface_map_.clear(); |
| +#endif |
| } |
| void GLES2DecoderImpl::SetSurface( |
| @@ -9008,6 +9045,98 @@ void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target, |
| BindAndApplyTextureParameters(info); |
| } |
| +#if defined(USE_X11) |
| +void GLES2DecoderImpl::ReleaseGLXPixmapForTexture(GLuint texture_id) { |
| + TextureToPixmapGLSurfaceMap::iterator it = |
| + texture_to_pixmap_gl_surface_map_.find(texture_id); |
| + if (it != texture_to_pixmap_gl_surface_map_.end()) { |
| + // Found a previous GLXPixmap bound to this texture; release it. |
| + scoped_refptr<gfx::GLSurface> pixmap_gl_surface = it->second; |
| + glXReleaseTexImageEXT( |
| + static_cast<gfx::GLContextGLX*>(GetGLContext())->display(), |
| + reinterpret_cast<GLXDrawable>(pixmap_gl_surface->GetHandle()), |
| + GLX_FRONT_LEFT_EXT); |
| + texture_to_pixmap_gl_surface_map_.erase(it); |
| + } |
| +} |
| +#endif |
| + |
| +void GLES2DecoderImpl::DoTexImagePixmap2DCHROMIUM( |
| + GLenum target, GLuint pixmap_id) { |
| +#if defined(USE_X11) |
| + if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) { |
| + SetGLError(GL_INVALID_OPERATION, |
| + "glTexImageXPixmap2DCHROMIUM", "only supported on desktop GL"); |
| + return; |
| + } |
| + |
| + if (target != GL_TEXTURE_2D) { |
| + // This might be supported in the future. |
| + SetGLError( |
| + GL_INVALID_OPERATION, |
| + "glTexImagePixmap2DCHROMIUM", "requires TEXTURE_2D target"); |
| + return; |
| + } |
| + |
| + TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); |
| + if (!info) { |
| + SetGLError(GL_INVALID_OPERATION, |
| + "glTexImagePixmap2DCHROMIUM", "no texture bound"); |
| + return; |
| + } |
| + if (info == texture_manager()->GetDefaultTextureInfo(target)) { |
|
greggman
2012/06/13 00:15:51
Have you considered a new function
GetTextureInfo
|
| + // Maybe this is conceptually valid, but disallow it to avoid accidents. |
| + SetGLError(GL_INVALID_OPERATION, |
| + "glTexImagePixmap2DCHROMIUM", "can't bind default texture"); |
| + return; |
| + } |
| + |
| + if (pixmap_id) { |
| + scoped_refptr<gfx::GLSurface> pixmap_gl_surface; |
| + |
| + TextureToPixmapGLSurfaceMap::iterator it = |
| + texture_to_pixmap_gl_surface_map_.find(info->service_id()); |
| + if (it == texture_to_pixmap_gl_surface_map_.end() || |
| + reinterpret_cast<XID>(it->second->GetShareHandle()) != pixmap_id) { |
| + pixmap_gl_surface = new gfx::PixmapGLSurfaceGLX(pixmap_id); |
| + if (!pixmap_gl_surface->Initialize()) { |
| + SetGLError(GL_INVALID_OPERATION, |
| + "glTexImagePixmap2DCHROMIUM", "fail to create GLXPixmap " |
| + "from Pixmap with the given ID"); |
| + return; |
| + } |
| + } else { |
| + pixmap_gl_surface = it->second; |
| + } |
| + |
| + // Release any GLXPixmap previously bound to this texture. |
| + ReleaseGLXPixmapForTexture(info->service_id()); |
| + |
| + glXBindTexImageEXT( |
| + static_cast<gfx::GLContextGLX*>(GetGLContext())->display(), |
| + reinterpret_cast<GLXDrawable>(pixmap_gl_surface->GetHandle()), |
| + GLX_FRONT_LEFT_EXT, |
| + 0); |
| + |
| + texture_to_pixmap_gl_surface_map_.insert( |
| + std::make_pair(info->service_id(), pixmap_gl_surface)); |
| + |
| + gfx::Size size = pixmap_gl_surface->GetSize(); |
| + texture_manager()->SetLevelInfo( |
|
greggman
2012/06/13 00:15:51
So mapping to a pix map magically sets the format
|
| + info, target, 0, GL_BGRA, size.width(), size.height(), 1, 0, |
| + GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, true); |
| + } else { |
| + // Release any GLXPixmap previously bound to this texture. |
| + ReleaseGLXPixmapForTexture(info->service_id()); |
| + |
| + texture_manager()->SetLevelCleared(info, GL_TEXTURE_2D, 0); |
| + } |
| +#else |
| + SetGLError(GL_INVALID_OPERATION, |
| + "glTexImagePixmap2DCHROMIUM", "not supported"); |
| +#endif |
| +} |
| + |
| // Include the auto-generated part of this file. We split this because it means |
| // we can easily edit the non-auto generated parts right here in this file |
| // instead of having to edit some template or the code generator. |