Bug 680644 - Let glxtest use a XWindow instead of a GLXPixmap - r=bjacob
authorMartin Vogt <martin.vogt@itwm.fraunhofer.de>
Wed, 22 Aug 2012 23:16:30 -0400
changeset 105737 e461878f0567a55a1eee4f118f8c970f618929e7
parent 105736 ff1f9b1ddc2ac162e2fa266288406c5b1852d468
child 105738 920d71aa1d2cac4290607eca2aa9e973a69ae387
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
reviewersbjacob
bugs680644
milestone18.0a1
Bug 680644 - Let glxtest use a XWindow instead of a GLXPixmap - r=bjacob This simplifies code and avoids a X server crash with certain FGLRX setups.
toolkit/xre/glxtest.cpp
--- a/toolkit/xre/glxtest.cpp
+++ b/toolkit/xre/glxtest.cpp
@@ -111,87 +111,75 @@ static void glxtest()
   PFNGLXQUERYVERSION glXQueryVersion = cast<PFNGLXQUERYVERSION>(dlsym(libgl, "glXQueryVersion"));
 
   typedef GLXFBConfig* (* PFNGLXCHOOSEFBCONFIG) (Display *, int, const int *, int *);
   PFNGLXCHOOSEFBCONFIG glXChooseFBConfig = cast<PFNGLXCHOOSEFBCONFIG>(glXGetProcAddress("glXChooseFBConfig"));
 
   typedef XVisualInfo* (* PFNGLXGETVISUALFROMFBCONFIG) (Display *, GLXFBConfig);
   PFNGLXGETVISUALFROMFBCONFIG glXGetVisualFromFBConfig = cast<PFNGLXGETVISUALFROMFBCONFIG>(glXGetProcAddress("glXGetVisualFromFBConfig"));
 
-  typedef GLXPixmap (* PFNGLXCREATEPIXMAP) (Display *, GLXFBConfig, Pixmap, const int *);
-  PFNGLXCREATEPIXMAP glXCreatePixmap = cast<PFNGLXCREATEPIXMAP>(glXGetProcAddress("glXCreatePixmap"));
-
   typedef GLXContext (* PFNGLXCREATENEWCONTEXT) (Display *, GLXFBConfig, int, GLXContext, Bool);
   PFNGLXCREATENEWCONTEXT glXCreateNewContext = cast<PFNGLXCREATENEWCONTEXT>(glXGetProcAddress("glXCreateNewContext"));
 
   typedef Bool (* PFNGLXMAKECURRENT) (Display*, GLXDrawable, GLXContext);
   PFNGLXMAKECURRENT glXMakeCurrent = cast<PFNGLXMAKECURRENT>(glXGetProcAddress("glXMakeCurrent"));
 
-  typedef void (* PFNGLXDESTROYPIXMAP) (Display *, GLXPixmap);
-  PFNGLXDESTROYPIXMAP glXDestroyPixmap = cast<PFNGLXDESTROYPIXMAP>(glXGetProcAddress("glXDestroyPixmap"));
-
   typedef void (* PFNGLXDESTROYCONTEXT) (Display*, GLXContext);
   PFNGLXDESTROYCONTEXT glXDestroyContext = cast<PFNGLXDESTROYCONTEXT>(glXGetProcAddress("glXDestroyContext"));
 
   typedef GLubyte* (* PFNGLGETSTRING) (GLenum);
   PFNGLGETSTRING glGetString = cast<PFNGLGETSTRING>(glXGetProcAddress("glGetString"));
 
   if (!glXQueryExtension ||
       !glXQueryVersion ||
       !glXChooseFBConfig ||
       !glXGetVisualFromFBConfig ||
-      !glXCreatePixmap ||
       !glXCreateNewContext ||
       !glXMakeCurrent ||
-      !glXDestroyPixmap ||
       !glXDestroyContext ||
       !glGetString)
   {
     fatal_error("glXGetProcAddress couldn't find required functions");
   }
   ///// Open a connection to the X server /////
   Display *dpy = XOpenDisplay(NULL);
   if (!dpy)
     fatal_error("Unable to open a connection to the X server");
   
   ///// Check that the GLX extension is present /////
   if (!glXQueryExtension(dpy, NULL, NULL))
     fatal_error("GLX extension missing");
-  
-  ///// Check that the GLX version is >= 1.3, needed for glXCreatePixmap, bug 659932 /////
-  int majorVersion, minorVersion;
-  if (!glXQueryVersion(dpy, &majorVersion, &minorVersion))
-    fatal_error("Unable to query GLX version");
-
-  if (majorVersion < 1 || (majorVersion == 1 && minorVersion < 3))
-    fatal_error("GLX version older than the required 1.3");
 
   XSetErrorHandler(x_error_handler);
 
   ///// Get a FBConfig and a visual /////
-  int attribs[] = {
-    GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
-    GLX_X_RENDERABLE, True,
-    0
-  };
   int numReturned;
-  GLXFBConfig *fbConfigs = glXChooseFBConfig(dpy, DefaultScreen(dpy), attribs, &numReturned );
+  GLXFBConfig *fbConfigs = glXChooseFBConfig(dpy, DefaultScreen(dpy), NULL, &numReturned );
   if (!fbConfigs)
     fatal_error("No FBConfigs found");
   XVisualInfo *vInfo = glXGetVisualFromFBConfig(dpy, fbConfigs[0]);
   if (!vInfo)
     fatal_error("No visual found for first FBConfig");
 
-  ///// Get a Pixmap and a GLXPixmap /////
-  Pixmap pixmap = XCreatePixmap(dpy, RootWindow(dpy, vInfo->screen), 4, 4, vInfo->depth);
-  GLXPixmap glxpixmap = glXCreatePixmap(dpy, fbConfigs[0], pixmap, NULL);
+  // using a X11 Window instead of a GLXPixmap does not crash
+  // fglrx in indirect rendering. bug 680644
+  Window win1;
+  XSetWindowAttributes swa;
+  swa.colormap = XCreateColormap(dpy, RootWindow(dpy, vInfo->screen),
+                                 vInfo->visual, AllocNone);
+  swa.border_pixel = 0;
+  win1 = XCreateWindow(dpy, RootWindow(dpy, vInfo->screen),
+                       10, 10, 16, 16,
+                       0, vInfo->depth, InputOutput, vInfo->visual,
+                       CWBorderPixel | CWColormap, &swa);
+
 
   ///// Get a GL context and make it current //////
   GLXContext context = glXCreateNewContext(dpy, fbConfigs[0], GLX_RGBA_TYPE, NULL, True);
-  glXMakeCurrent(dpy, glxpixmap, context);
+  glXMakeCurrent(dpy, win1, context);
 
   ///// Look for this symbol to determine texture_from_pixmap support /////
   void* glXBindTexImageEXT = glXGetProcAddress("glXBindTexImageEXT"); 
 
   ///// Get GL vendor/renderer/versions strings /////
   enum { bufsize = 1024 };
   char buf[bufsize];
   const GLubyte *vendorString = glGetString(GL_VENDOR);
@@ -210,18 +198,17 @@ static void glxtest()
   if (length >= bufsize)
     fatal_error("GL strings length too large for buffer size");
 
   ///// Clean up. Indeed, the parent process might fail to kill us (e.g. if it doesn't need to check GL info)
   ///// so we might be staying alive for longer than expected, so it's important to consume as little memory as
   ///// possible. Also we want to check that we're able to do that too without generating X errors.
   glXMakeCurrent(dpy, None, NULL); // must release the GL context before destroying it
   glXDestroyContext(dpy, context);
-  glXDestroyPixmap(dpy, glxpixmap);
-  XFreePixmap(dpy, pixmap);
+  XDestroyWindow(dpy,win1);
   XCloseDisplay(dpy);
   dlclose(libgl);
 
   ///// Finally write data to the pipe
   write(write_end_of_the_pipe, buf, length);
 }
 
 /** \returns true in the child glxtest process, false in the parent process */