summaryrefslogtreecommitdiffstats
path: root/src/glx
diff options
context:
space:
mode:
Diffstat (limited to 'src/glx')
-rw-r--r--src/glx/x11/dri_glx.c22
-rw-r--r--src/glx/x11/glxclient.h2
-rw-r--r--src/glx/x11/glxcmds.c4
-rw-r--r--src/glx/x11/glxext.c19
4 files changed, 29 insertions, 18 deletions
diff --git a/src/glx/x11/dri_glx.c b/src/glx/x11/dri_glx.c
index a6581465bc2..08e419c1efb 100644
--- a/src/glx/x11/dri_glx.c
+++ b/src/glx/x11/dri_glx.c
@@ -742,6 +742,14 @@ static __GLXDRIcontext *driCreateContext(__GLXscreenConfigs *psc,
return NULL;
}
+static void driDestroyDrawable(__GLXDRIdrawable *pdraw)
+{
+ __GLXscreenConfigs *psc = pdraw->psc;
+
+ (*pdraw->driDrawable.destroyDrawable)(&pdraw->driDrawable);
+ XF86DRIDestroyDrawable(psc->dpy, psc->scr, pdraw->drawable);
+ Xfree(pdraw);
+}
static __GLXDRIdrawable *driCreateDrawable(__GLXscreenConfigs *psc,
GLXDrawable drawable,
@@ -777,12 +785,7 @@ static __GLXDRIdrawable *driCreateDrawable(__GLXscreenConfigs *psc,
return NULL;
}
- if (__glxHashInsert(psc->drawHash, drawable, pdraw)) {
- (*pdraw->driDrawable.destroyDrawable)(&pdraw->driDrawable);
- XF86DRIDestroyDrawable(psc->dpy, psc->scr, drawable);
- Xfree(pdraw);
- return NULL;
- }
+ pdraw->destroyDrawable = driDestroyDrawable;
return pdraw;
}
@@ -793,8 +796,6 @@ static void driDestroyScreen(__GLXscreenConfigs *psc)
if (psc->__driScreen.private)
(*psc->__driScreen.destroyScreen)(&psc->__driScreen);
psc->__driScreen.private = NULL;
- if (psc->drawHash)
- __glxHashDestroy(psc->drawHash);
if (psc->driver)
dlclose(psc->driver);
}
@@ -810,11 +811,6 @@ static __GLXDRIscreen *driCreateScreen(__GLXscreenConfigs *psc, int screen,
if (psp == NULL)
return NULL;
- /* Create drawable hash */
- psc->drawHash = __glxHashCreate();
- if ( psc->drawHash == NULL )
- return NULL;
-
/* Initialize per screen dynamic client GLX extensions */
psc->ext_list_first_time = GL_TRUE;
diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h
index 259add75958..730caf73024 100644
--- a/src/glx/x11/glxclient.h
+++ b/src/glx/x11/glxclient.h
@@ -132,6 +132,8 @@ struct __GLXDRIcontextRec {
};
struct __GLXDRIdrawableRec {
+ void (*destroyDrawable)(__GLXDRIdrawable *drawable);
+
XID drawable;
__GLXscreenConfigs *psc;
__DRIdrawable driDrawable;
diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c
index 1437ea54425..adf53116745 100644
--- a/src/glx/x11/glxcmds.c
+++ b/src/glx/x11/glxcmds.c
@@ -99,10 +99,8 @@ static void GarbageCollectDRIDrawables(Display *dpy, __GLXscreenConfigs *sc)
if (!windowExistsFlag) {
/* Destroy the local drawable data, if the drawable no
longer exists in the Xserver */
- (*pdraw->driDrawable.destroyDrawable)(&pdraw->driDrawable);
- XF86DRIDestroyDrawable(dpy, sc->scr, draw);
+ (*pdraw->destroyDrawable)(pdraw);
__glxHashDelete(sc->drawHash, draw);
- Xfree(pdraw);
}
} while (__glxHashNext(sc->drawHash, &draw, (void *)&pdraw) == 1);
}
diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c
index 077398fe33f..1d9be297414 100644
--- a/src/glx/x11/glxext.c
+++ b/src/glx/x11/glxext.c
@@ -350,6 +350,8 @@ static void FreeScreenConfigs(__GLXdisplayPrivate *priv)
#ifdef GLX_DIRECT_RENDERING
if (psc->driScreen)
psc->driScreen->destroyScreen(psc);
+ if (psc->drawHash)
+ __glxHashDestroy(psc->drawHash);
#endif
}
XFree((char*) priv->screenConfigs);
@@ -772,8 +774,15 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv)
psc->scr = i;
psc->dpy = dpy;
#ifdef GLX_DIRECT_RENDERING
- if (priv->driDisplay)
+ if (priv->driDisplay) {
+ /* Create drawable hash */
+ psc->drawHash = __glxHashCreate();
+ if (psc->drawHash == NULL)
+ continue;
psc->driScreen = (*priv->driDisplay->createScreen)(psc, i, priv);
+ if (psc->driScreen == NULL)
+ __glxHashDestroy(psc->drawHash);
+ }
#endif
}
SyncHandle();
@@ -1192,7 +1201,13 @@ FetchDRIDrawable(Display *dpy, GLXDrawable drawable, GLXContext gc)
if (__glxHashLookup(psc->drawHash, drawable, (void *) &pdraw) == 0)
return pdraw;
- return psc->driScreen->createDrawable(psc, drawable, gc);
+ pdraw = psc->driScreen->createDrawable(psc, drawable, gc);
+ if (__glxHashInsert(psc->drawHash, drawable, pdraw)) {
+ (*pdraw->destroyDrawable)(pdraw);
+ return NULL;
+ }
+
+ return pdraw;
}
#endif /* GLX_DIRECT_RENDERING */