#include #include #include #include // simple GLX Pixmap test-case demonstrating: // // 1) Destroying a GLX Pixmap makes any other GLX Pixmap that wraps // the same X Pixmap into a Bad Drawable // // 2) Such a double wrapping creates memory leak in the X server such // that three calls to this test program (on my machine) are // sufficient to cause all further invocations to throw BadAlloc // X errors. This happens whether the glXDestroyPixmap() is called // explicitly or not (in other words, whether we clean up after // ourselves or allow X to do so for us on program exit). // // gcc -I/usr/include/GL -lGL -lX11 -lXpm simple-test.c -o test Display *dpy; GLXContext ctx; Pixmap x_pixmap; GLXPixmap glx_pixmap_one; GLXPixmap glx_pixmap_two; GLXFBConfig *fb_config; int n_fb_configs; static int ctx_attr[] = { GLX_DOUBLEBUFFER, False, GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, GLX_BIND_TO_TEXTURE_RGB_EXT, True, None }; static int glxpix_attr[] = { GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT, GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, None }; int main(int argc, char **argv) { // open X connection dpy = XOpenDisplay(0); // grab a GL config and make a GL context (for direct rendering) fb_config = glXChooseFBConfig (dpy, 0, ctx_attr, &n_fb_configs); printf ("got %d appropriate fb configs\n", n_fb_configs); ctx = glXCreateNewContext (dpy, fb_config[0], GLX_RGBA_TYPE, NULL, True); // make an X pixmap x_pixmap = XCreatePixmap (dpy, DefaultRootWindow(dpy), 1024, 1024, 24); // wrap it in a glX pixmap glx_pixmap_one = glXCreatePixmap (dpy, fb_config[0], x_pixmap, glxpix_attr); // wrap it in a second glX pixmap glx_pixmap_two = glXCreatePixmap (dpy, fb_config[0], x_pixmap, glxpix_attr); // all pixels to red printf ("making glx pixmap the current gl context\n"); glXMakeCurrent (dpy, glx_pixmap_one, ctx); printf ("okay, that worked -- doing some sample gl work\n"); glViewport (0, 0, 1024, 1024); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glOrtho (-512.0, 512.0, -512.0, 512.0, -1.0, 1.0); glClearColor(1.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glFlush(); // write out -- just to show that things are working printf ("writing out red.xpm sanity check file\n"); XpmWriteFileFromPixmap (dpy, "red.xpm", x_pixmap, 0, NULL); // now try to use the second glx pixmap, then destroy it printf ("making the second glx pixmap current\n"); glXMakeCurrent (dpy, glx_pixmap_two, ctx); printf ("making nothing current\n"); glXMakeCurrent (dpy, None, NULL); // brings down server w/out this line printf ("destroying the second glx pixmap\n"); // // the problematic destroy // glXDestroyPixmap (dpy, glx_pixmap_two); // and try to use the first glx pixmap again printf ("making the first glx pixmap current again\n"); // all pixels to blue glXMakeCurrent (dpy, glx_pixmap_one, ctx); glViewport (0, 0, 1024, 1024); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glOrtho (-512.0, 512.0, -512.0, 512.0, -1.0, 1.0); glClearColor(0.0, 0.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glFlush(); // write out printf ("writing out a second sanity-check file\n"); XpmWriteFileFromPixmap (dpy, "blue.xpm", x_pixmap, 0, NULL); // clean up glXDestroyPixmap (dpy, glx_pixmap_one); XFreePixmap (dpy, x_pixmap); }