=== modified file 'src/composite-canvas-glx.cc'
@@ -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'
@@ -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'
@@ -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 */