summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2010-01-22 14:13:25 +0800
committerChia-I Wu <[email protected]>2010-01-22 14:54:40 +0800
commitfe0e35aba8bb2472630a18edb232d7379ef17eaf (patch)
tree6b5460d58dad6e5adf928bf4634b79155f34b2f9
parent0e54f9c529c0c015b3d227afff21da1f7b452991 (diff)
egl_xdri: Do not reinitialize in __glXInitialize.
__glXInitialize should return the same GLX display for the same X display. This issue is triggered by a35f6bb207efe3c959bbd16a37f2049e5aceeea9.
-rw-r--r--src/egl/drivers/xdri/egl_xdri.c1
-rw-r--r--src/egl/drivers/xdri/glxinit.c99
-rw-r--r--src/egl/drivers/xdri/glxinit.h3
3 files changed, 78 insertions, 25 deletions
diff --git a/src/egl/drivers/xdri/egl_xdri.c b/src/egl/drivers/xdri/egl_xdri.c
index 8425b3d11ef..e0761146daf 100644
--- a/src/egl/drivers/xdri/egl_xdri.c
+++ b/src/egl/drivers/xdri/egl_xdri.c
@@ -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;
diff --git a/src/egl/drivers/xdri/glxinit.c b/src/egl/drivers/xdri/glxinit.c
index 77750093944..5c0fbc6b3c3 100644
--- a/src/egl/drivers/xdri/glxinit.c
+++ b/src/egl/drivers/xdri/glxinit.c
@@ -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;
}
diff --git a/src/egl/drivers/xdri/glxinit.h b/src/egl/drivers/xdri/glxinit.h
index 57206e627b2..1cc7c460fe2 100644
--- a/src/egl/drivers/xdri/glxinit.h
+++ b/src/egl/drivers/xdri/glxinit.h
@@ -8,7 +8,4 @@
extern void
_gl_context_modes_destroy(__GLcontextModes * modes);
-extern void
-__glXRelease(__GLXdisplayPrivate *dpyPriv);
-
#endif /* GLXINIT_INCLUDED */