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. |