=== modified file 'src/composite-canvas-glx.cc'
--- src/composite-canvas-glx.cc	2011-07-15 13:01:34 +0000
+++ src/composite-canvas-glx.cc	2011-07-19 21:34:08 +0000
@@ -34,6 +34,7 @@
 #include "log.h"
 
 PFNGLXBINDTEXIMAGEEXTPROC glXBindTexImageEXT_;
+PFNGLXRELEASETEXIMAGEEXTPROC glXReleaseTexImageEXT_;
 PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT_;
 PFNGLXSWAPINTERVALMESAPROC glXSwapIntervalMESA_;
 
@@ -73,9 +74,12 @@
         glXBindTexImageEXT_ =
             reinterpret_cast<PFNGLXBINDTEXIMAGEEXTPROC>(
                 glXGetProcAddress((const GLubyte *)"glXBindTexImageEXT"));
+        glXReleaseTexImageEXT_ =
+            reinterpret_cast<PFNGLXRELEASETEXIMAGEEXTPROC>(
+                glXGetProcAddress((const GLubyte *)"glXReleaseTexImageEXT"));
     }
 
-    if (!glXBindTexImageEXT_) {
+    if (!glXBindTexImageEXT_ || !glXReleaseTexImageEXT_) {
         Log::info("** GLX does not support GLX_EXT_texture_from_pixmap!\n");
     }
 
@@ -117,6 +121,8 @@
         GLX_ALPHA_SIZE, 1,
         GLX_DEPTH_SIZE, 1,
         GLX_DOUBLEBUFFER, True,
+        GLX_BIND_TO_TEXTURE_RGBA_EXT, True,
+        GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
         None
     };
     int num_configs;

=== modified file 'src/composite-window-glxpixmap.cc'
--- src/composite-window-glxpixmap.cc	2011-04-04 12:56:06 +0000
+++ src/composite-window-glxpixmap.cc	2011-07-20 09:17:11 +0000
@@ -32,11 +32,23 @@
 #include "log.h"
 
 extern PFNGLXBINDTEXIMAGEEXTPROC glXBindTexImageEXT_;
+extern PFNGLXRELEASETEXIMAGEEXTPROC glXReleaseTexImageEXT_;
 
-CompositeWindowGLXPixmap::~CompositeWindowGLXPixmap()
+void
+CompositeWindowGLXPixmap::release_tfp()
 {
     if (glx_pixmap_)
+    {
+        glXReleaseTexImageEXT_(xdpy_, glx_pixmap_, GLX_FRONT_LEFT_EXT);
         glXDestroyPixmap(xdpy_, glx_pixmap_);
+        glx_pixmap_ = 0;
+        glx_pixmap_bound_ = false;
+    }
+}
+
+CompositeWindowGLXPixmap::~CompositeWindowGLXPixmap()
+{
+    release_tfp();
 }
 
 void
@@ -51,10 +63,7 @@
     Profiler::ScopedSamples scoped_tfp(CompositeWindow::get_profiler_tfp_pair());
 
     if (recreate) {
-        if (glx_pixmap_) {
-            glXDestroyPixmap(xdpy_, glx_pixmap_);
-            glx_pixmap_ = 0;
-        }
+        release_tfp();
         glx_pixmap_ = glXCreatePixmap(xdpy_, glx_fbconfig_, pix_,
                                       pixmap_attribs);
 
@@ -64,7 +73,40 @@
     /* Update texture with new data */
     glXWaitX();
 
+    /*
+     * According to the spec, proper TFP usage is:
+     *
+     * while(1) {
+     *     glXWaitX();
+     *     glXBindTexImageEXT();
+     *     <Render using texture>
+     *     glXReleaseTexImageEXT();
+     * }
+     *
+     * we are using:
+     *
+     * while(1) {
+     *     glXWaitX();
+     *     if (bound) glXReleaseTexImageEXT();
+     *     glxBindTexImageEXT();
+     *     <Render using texture>
+     * }
+     *
+     * The only potential problem here is that rendering to a pixmap bound to a
+     * texture leaves the contents of the texture in an undefined state
+     * (according to the spec).  We are not performing any explicit pixmap
+     * rendering, but we do get implicit pixmap changes due to window
+     * redirection. It is not clear if these changes should affect the texture.
+     *
+     * In any case, both compiz and cogl/clutter handle TFP this
+     * way, so it seems to be safe for now for all drivers.
+     */
     glBindTexture(GL_TEXTURE_2D, tex_);
 
+    if (glx_pixmap_bound_)
+        glXReleaseTexImageEXT_(xdpy_, glx_pixmap_, GLX_FRONT_LEFT_EXT);
+
     glXBindTexImageEXT_(xdpy_, glx_pixmap_, GLX_FRONT_LEFT_EXT, NULL);
+
+    glx_pixmap_bound_ = true;
 }

=== modified file 'src/composite-window-glxpixmap.h'
--- src/composite-window-glxpixmap.h	2011-07-15 08:16:54 +0000
+++ src/composite-window-glxpixmap.h	2011-07-20 08:23:33 +0000
@@ -34,14 +34,16 @@
     CompositeWindowGLXPixmap(Display *xdpy, Window win,
                              GLXFBConfig glx_fbconfig) :
         CompositeWindowGL(xdpy, win), glx_pixmap_(0),
-        glx_fbconfig_ (glx_fbconfig) {}
+        glx_fbconfig_ (glx_fbconfig), glx_pixmap_bound_(false) {}
     ~CompositeWindowGLXPixmap();
 
     void update_texture_from_pixmap(bool recreate);
 
 private:
+    void release_tfp();
     GLXPixmap glx_pixmap_;
     GLXFBConfig glx_fbconfig_;
+    bool glx_pixmap_bound_;
 };
 
 #endif /* COMPOSITE_WINDOW_GLXPIXMAP_H */

