egl_xdri: Do not reinitialize in __glXInitialize.
authorChia-I Wu <olvaffe@gmail.com>
Fri, 22 Jan 2010 06:13:25 +0000 (14:13 +0800)
committerChia-I Wu <olvaffe@gmail.com>
Fri, 22 Jan 2010 06:54:40 +0000 (14:54 +0800)
__glXInitialize should return the same GLX display for the same X
display.  This issue is triggered by
a35f6bb207efe3c959bbd16a37f2049e5aceeea9.

src/egl/drivers/xdri/egl_xdri.c
src/egl/drivers/xdri/glxinit.c
src/egl/drivers/xdri/glxinit.h

index 8425b3d11efab7e6d48d271eaf440a20d77dbae2..e0761146daf584ae0dc569db6504a4f4fb4221eb 100644 (file)
@@ -342,7 +342,6 @@ xdri_eglTerminate(_EGLDriver *drv, _EGLDisplay *dpy)
    }
 
    xdri_dpy->driDisplay->destroyDisplay(xdri_dpy->driDisplay);
-   __glXRelease(xdri_dpy->dpyPriv);
 
    free(xdri_dpy);
    dpy->DriverData = NULL;
index 77750093944d51e1db1ae4f66555a6519d4a5a02..5c0fbc6b3c365cb9bfa8cee1d97368c5b4278786 100644 (file)
@@ -1,8 +1,10 @@
 /**
  * GLX initialization.  Code based on glxext.c, glx_query.c, and
- * glcontextmodes.c under src/glx/x11/.  The major difference is that no DRI
- * related code here.
+ * glcontextmodes.c under src/glx/x11/.  The major difference is that DRI
+ * related code is stripped out.
  *
+ * If the maintenance of this file takes too much time, we should consider
+ * refactoring glxext.c.
  */
 
 #include <assert.h>
@@ -31,7 +33,26 @@ typedef struct GLXGenericGetString
 static char *__glXExtensionName = GLX_EXTENSION_NAME;
 static XExtensionInfo *__glXExtensionInfo = NULL;
 
-static /* const */ XExtensionHooks __glXExtensionHooks = { NULL };
+static int
+__glXCloseDisplay(Display * dpy, XExtCodes * codes)
+{
+   return XextRemoveDisplay(__glXExtensionInfo, dpy);
+}
+
+static /* const */ XExtensionHooks __glXExtensionHooks = {
+  NULL,                   /* create_gc */
+  NULL,                   /* copy_gc */
+  NULL,                   /* flush_gc */
+  NULL,                   /* free_gc */
+  NULL,                   /* create_font */
+  NULL,                   /* free_font */
+  __glXCloseDisplay,      /* close_display */
+  NULL,                   /* wire_to_event */
+  NULL,                   /* event_to_wire */
+  NULL,                   /* error */
+  NULL,                   /* error_string */
+};
+
 static
 XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo,
                            __glXExtensionName, &__glXExtensionHooks,
@@ -180,6 +201,30 @@ FreeScreenConfigs(__GLXdisplayPrivate * priv)
    priv->screenConfigs = NULL;
 }
 
+/*
+** Release the private memory referred to in a display private
+** structure.  The caller will free the extension structure.
+*/
+static int
+__glXFreeDisplayPrivate(XExtData * extension)
+{
+   __GLXdisplayPrivate *priv;
+
+   priv = (__GLXdisplayPrivate *) extension->private_data;
+   FreeScreenConfigs(priv);
+   if (priv->serverGLXvendor) {
+      Xfree((char *) priv->serverGLXvendor);
+      priv->serverGLXvendor = 0x0;      /* to protect against double free's */
+   }
+   if (priv->serverGLXversion) {
+      Xfree((char *) priv->serverGLXversion);
+      priv->serverGLXversion = 0x0;     /* to protect against double free's */
+   }
+
+   Xfree((char *) priv);
+   return 0;
+}
+
 /************************************************************************/
 
 /*
@@ -570,40 +615,40 @@ AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv)
    return GL_TRUE;
 }
 
-_X_HIDDEN void
-__glXRelease(__GLXdisplayPrivate *dpyPriv)
-{
-   FreeScreenConfigs(dpyPriv);
-
-   if (dpyPriv->serverGLXvendor) {
-      Xfree((char *) dpyPriv->serverGLXvendor);
-      dpyPriv->serverGLXvendor = NULL;
-   }
-   if (dpyPriv->serverGLXversion) {
-      Xfree((char *) dpyPriv->serverGLXversion);
-      dpyPriv->serverGLXversion = NULL;
-   }
-
-   Xfree(dpyPriv);
-}
-
 _X_HIDDEN __GLXdisplayPrivate *
 __glXInitialize(Display * dpy)
 {
    XExtDisplayInfo *info = __glXFindDisplay(dpy);
+   XExtData **privList, *private, *found;
    __GLXdisplayPrivate *dpyPriv;
+   XEDataObject dataObj;
    int major, minor;
 
    if (!XextHasExtension(info))
       return NULL;
 
+   /* See if a display private already exists.  If so, return it */
+   dataObj.display = dpy;
+   privList = XEHeadOfExtensionList(dataObj);
+   found = XFindOnExtensionList(privList, info->codes->extension);
+   if (found)
+      return (__GLXdisplayPrivate *) found->private_data;
+
    /* See if the versions are compatible */
    if (!QueryVersion(dpy, info->codes->major_opcode, &major, &minor))
       return NULL;
 
+   /*
+    ** Allocate memory for all the pieces needed for this buffer.
+    */
+   private = (XExtData *) Xmalloc(sizeof(XExtData));
+   if (!private)
+      return NULL;
    dpyPriv = (__GLXdisplayPrivate *) Xcalloc(1, sizeof(__GLXdisplayPrivate));
-   if (!dpyPriv)
+   if (!dpyPriv) {
+      Xfree(private);
       return NULL;
+   }
 
    /*
     ** Init the display private and then read in the screen config
@@ -619,8 +664,20 @@ __glXInitialize(Display * dpy)
 
    if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) {
       Xfree(dpyPriv);
+      Xfree(private);
       return NULL;
    }
 
+   /*
+    ** Fill in the private structure.  This is the actual structure that
+    ** hangs off of the Display structure.  Our private structure is
+    ** referred to by this structure.  Got that?
+    */
+   private->number = info->codes->extension;
+   private->next = 0;
+   private->free_private = __glXFreeDisplayPrivate;
+   private->private_data = (char *) dpyPriv;
+   XAddToExtensionList(privList, private);
+
    return dpyPriv;
 }
index 57206e627b2e8519ff85cfda8c349675cd29f520..1cc7c460fe27da20f076176cb4f767cbb997fea1 100644 (file)
@@ -8,7 +8,4 @@
 extern void
 _gl_context_modes_destroy(__GLcontextModes * modes);
 
-extern void
-__glXRelease(__GLXdisplayPrivate *dpyPriv);
-
 #endif /* GLXINIT_INCLUDED */