summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--GL/glx/glxdri.c26
-rw-r--r--GL/glx/glxext.c7
-rw-r--r--GL/glx/glxserver.h2
-rw-r--r--hw/xfree86/dri/dri.c139
-rw-r--r--hw/xfree86/dri/dri.h6
-rw-r--r--hw/xfree86/dri/dristruct.h1
-rw-r--r--hw/xfree86/dri/xf86dri.c11
7 files changed, 130 insertions, 62 deletions
diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c
index efa02f842..db564c098 100644
--- a/GL/glx/glxdri.c
+++ b/GL/glx/glxdri.c
@@ -758,9 +758,16 @@ static __DRIscreen *findScreen(__DRInativeDisplay *dpy, int scrn)
static GLboolean windowExists(__DRInativeDisplay *dpy, __DRIid draw)
{
- WindowPtr pWin = (WindowPtr) LookupIDByType(draw, RT_WINDOW);
-
- return pWin == NULL ? GL_FALSE : GL_TRUE;
+ DrawablePtr pDrawable = (DrawablePtr) LookupIDByType(draw, RT_WINDOW);
+ int unused;
+ drm_clip_rect_t *pRects;
+
+ return pDrawable ? DRIGetDrawableInfo(pDrawable->pScreen, pDrawable,
+ (unsigned*)&unused, (unsigned*)&unused,
+ &unused, &unused, &unused, &unused,
+ &unused, &pRects, &unused, &unused,
+ &unused, &pRects)
+ : GL_FALSE;
}
static GLboolean createContext(__DRInativeDisplay *dpy, int screen,
@@ -815,10 +822,8 @@ createDrawable(__DRInativeDisplay *dpy, int screen,
return GL_FALSE;
__glXDRIenterServer(GL_FALSE);
- retval = DRICreateDrawable(screenInfo.screens[screen],
- drawable,
- pDrawable,
- hHWDrawable);
+ retval = DRICreateDrawable(screenInfo.screens[screen], __pGlxClient,
+ pDrawable, hHWDrawable);
__glXDRIleaveServer(GL_FALSE);
return retval;
}
@@ -834,9 +839,8 @@ destroyDrawable(__DRInativeDisplay *dpy, int screen, __DRIid drawable)
return GL_FALSE;
__glXDRIenterServer(GL_FALSE);
- retval = DRIDestroyDrawable(screenInfo.screens[screen],
- drawable,
- pDrawable);
+ retval = DRIDestroyDrawable(screenInfo.screens[screen], __pGlxClient,
+ pDrawable);
__glXDRIleaveServer(GL_FALSE);
return retval;
}
@@ -927,7 +931,7 @@ getDrawableInfo(__DRInativeDisplay *dpy, int screen,
*ppBackClipRects = NULL;
}
- return GL_TRUE;
+ return retval;
}
static int
diff --git a/GL/glx/glxext.c b/GL/glx/glxext.c
index c09120c12..b4f3105aa 100644
--- a/GL/glx/glxext.c
+++ b/GL/glx/glxext.c
@@ -62,6 +62,11 @@ xGLXSingleReply __glXReply;
static __GLXclientState *__glXClients[MAXCLIENTS + 1];
/*
+** Client that called into GLX dispatch.
+*/
+ClientPtr __pGlxClient;
+
+/*
** Forward declarations.
*/
static int __glXDispatch(ClientPtr);
@@ -549,6 +554,8 @@ static int __glXDispatch(ClientPtr client)
GLboolean rendering = opcode <= X_GLXRenderLarge;
__glXleaveServer(rendering);
+ __pGlxClient = client;
+
retval = (*proc)(cl, (GLbyte *) stuff);
__glXenterServer(rendering);
diff --git a/GL/glx/glxserver.h b/GL/glx/glxserver.h
index fa09c1546..b6b55927e 100644
--- a/GL/glx/glxserver.h
+++ b/GL/glx/glxserver.h
@@ -110,6 +110,8 @@ void __glXScreenInitVisuals(__GLXscreen *screen);
extern __GLXcontext *__glXLastContext;
extern __GLXcontext *__glXForceCurrent(__GLXclientState*, GLXContextTag, int*);
+extern ClientPtr __pGlxClient;
+
int __glXError(int error);
/*
diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c
index 2a53eae1a..6c640d806 100644
--- a/hw/xfree86/dri/dri.c
+++ b/hw/xfree86/dri/dri.c
@@ -593,6 +593,10 @@ DRIFinishScreenInit(ScreenPtr pScreen)
pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures;
pScreen->WindowExposures = pDRIInfo->wrap.WindowExposures;
}
+
+ pDRIPriv->DestroyWindow = pScreen->DestroyWindow;
+ pScreen->DestroyWindow = DRIDestroyWindow;
+
if (pDRIInfo->wrap.CopyWindow) {
pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow;
pScreen->CopyWindow = pDRIInfo->wrap.CopyWindow;
@@ -642,6 +646,10 @@ DRICloseScreen(ScreenPtr pScreen)
pScreen->WindowExposures = pDRIPriv->wrap.WindowExposures;
pDRIPriv->wrap.WindowExposures = NULL;
}
+ if (pDRIPriv->DestroyWindow) {
+ pScreen->DestroyWindow = pDRIPriv->DestroyWindow;
+ pDRIPriv->DestroyWindow = NULL;
+ }
if (pDRIInfo->wrap.CopyWindow) {
pScreen->CopyWindow = pDRIPriv->wrap.CopyWindow;
pDRIPriv->wrap.CopyWindow = NULL;
@@ -1248,8 +1256,8 @@ DRIDecreaseNumberVisible(ScreenPtr pScreen)
}
Bool
-DRICreateDrawable(ScreenPtr pScreen, Drawable id,
- DrawablePtr pDrawable, drm_drawable_t * hHWDrawable)
+DRICreateDrawable(ScreenPtr pScreen, ClientPtr client, DrawablePtr pDrawable,
+ drm_drawable_t * hHWDrawable)
{
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
DRIDrawablePrivPtr pDRIDrawablePriv;
@@ -1291,11 +1299,12 @@ DRICreateDrawable(ScreenPtr pScreen, Drawable id,
if (pDRIDrawablePriv->nrects)
DRIIncreaseNumberVisible(pScreen);
-
- /* track this in case this window is destroyed */
- AddResource(id, DRIDrawablePrivResType, (pointer)pWin);
}
+ /* track this in case the client dies */
+ AddResource(FakeClientID(client->index), DRIDrawablePrivResType,
+ (pointer)pDrawable->id);
+
if (pDRIDrawablePriv->hwDrawable) {
drmUpdateDrawableInfo(pDRIPriv->drmFD,
pDRIDrawablePriv->hwDrawable,
@@ -1313,21 +1322,59 @@ DRICreateDrawable(ScreenPtr pScreen, Drawable id,
return TRUE;
}
-Bool
-DRIDestroyDrawable(ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable)
+static void
+DRIDrawablePrivDestroy(WindowPtr pWin)
{
- DRIDrawablePrivPtr pDRIDrawablePriv;
- WindowPtr pWin;
+ DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
+ ScreenPtr pScreen;
+ DRIScreenPrivPtr pDRIPriv;
+
+ if (!pDRIDrawablePriv)
+ return;
+
+ pScreen = pWin->drawable.pScreen;
+ pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (pDRIDrawablePriv->drawableIndex != -1) {
+ /* bump stamp to force outstanding 3D requests to resync */
+ pDRIPriv->pSAREA->drawableTable[pDRIDrawablePriv->drawableIndex].stamp
+ = DRIDrawableValidationStamp++;
+
+ /* release drawable table entry */
+ pDRIPriv->DRIDrawables[pDRIDrawablePriv->drawableIndex] = NULL;
+ }
+
+ pDRIPriv->nrWindows--;
+
+ if (pDRIDrawablePriv->nrects)
+ DRIDecreaseNumberVisible(pScreen);
+
+ drmDestroyDrawable(pDRIPriv->drmFD, pDRIDrawablePriv->hwDrawable);
+
+ xfree(pDRIDrawablePriv);
+ pWin->devPrivates[DRIWindowPrivIndex].ptr = NULL;
+}
+
+static Bool
+DRIDestroyDrawableCB(pointer value, XID id, pointer data)
+{
+ if (value == data) {
+ /* This calls back DRIDrawablePrivDelete which frees private area */
+ FreeResourceByType(id, DRIDrawablePrivResType, FALSE);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+Bool
+DRIDestroyDrawable(ScreenPtr pScreen, ClientPtr client, DrawablePtr pDrawable)
+{
if (pDrawable->type == DRAWABLE_WINDOW) {
- pWin = (WindowPtr)pDrawable;
- pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
- pDRIDrawablePriv->refCount--;
- if (pDRIDrawablePriv->refCount <= 0) {
- /* This calls back DRIDrawablePrivDelete which frees private area */
- FreeResourceByType(id, DRIDrawablePrivResType, FALSE);
- }
+ LookupClientResourceComplex(client, DRIDrawablePrivResType,
+ DRIDestroyDrawableCB,
+ (pointer)pDrawable->id);
}
else { /* pixmap (or for GLX 1.3, a PBuffer) */
/* NOT_DONE */
@@ -1340,43 +1387,26 @@ DRIDestroyDrawable(ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable)
Bool
DRIDrawablePrivDelete(pointer pResource, XID id)
{
- DrawablePtr pDrawable = (DrawablePtr)pResource;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pDrawable->pScreen);
- DRIDrawablePrivPtr pDRIDrawablePriv;
- WindowPtr pWin;
-
- if (pDrawable->type == DRAWABLE_WINDOW) {
- pWin = (WindowPtr)pDrawable;
- pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
+ WindowPtr pWin;
- if (pDRIDrawablePriv->drawableIndex != -1) {
- /* bump stamp to force outstanding 3D requests to resync */
- pDRIPriv->pSAREA->drawableTable[pDRIDrawablePriv->drawableIndex].stamp
- = DRIDrawableValidationStamp++;
+ id = (XID)pResource;
+ pWin = LookupIDByType(id, RT_WINDOW);
- /* release drawable table entry */
- pDRIPriv->DRIDrawables[pDRIDrawablePriv->drawableIndex] = NULL;
- }
+ if (pWin) {
+ DRIDrawablePrivPtr pDRIDrwPriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
- if (drmDestroyDrawable(pDRIPriv->drmFD,
- pDRIDrawablePriv->hwDrawable)) {
+ if (!pDRIDrwPriv)
return FALSE;
- }
- xfree(pDRIDrawablePriv);
- pWin->devPrivates[DRIWindowPrivIndex].ptr = NULL;
+ if (--pDRIDrwPriv->refCount == 0)
+ DRIDrawablePrivDestroy(pWin);
- pDRIPriv->nrWindows--;
-
- if (REGION_NUM_RECTS(&pWin->clipList))
- DRIDecreaseNumberVisible(pDrawable->pScreen);
+ return TRUE;
}
else { /* pixmap (or for GLX 1.3, a PBuffer) */
/* NOT_DONE */
return FALSE;
}
-
- return TRUE;
}
Bool
@@ -1884,6 +1914,31 @@ DRITreeTraversal(WindowPtr pWin, pointer data)
return WT_WALKCHILDREN;
}
+Bool
+DRIDestroyWindow(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ Bool retval = TRUE;
+
+ DRIDrawablePrivDestroy(pWin);
+
+ /* call lower wrapped functions */
+ if(pDRIPriv->DestroyWindow) {
+ /* unwrap */
+ pScreen->DestroyWindow = pDRIPriv->DestroyWindow;
+
+ /* call lower layers */
+ retval = (*pScreen->DestroyWindow)(pWin);
+
+ /* rewrap */
+ pDRIPriv->DestroyWindow = pScreen->DestroyWindow;
+ pScreen->DestroyWindow = DRIDestroyWindow;
+ }
+
+ return retval;
+}
+
void
DRICopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
{
diff --git a/hw/xfree86/dri/dri.h b/hw/xfree86/dri/dri.h
index e49bb6fa0..c0da7001e 100644
--- a/hw/xfree86/dri/dri.h
+++ b/hw/xfree86/dri/dri.h
@@ -231,12 +231,12 @@ extern Bool DRIDestroyContext(ScreenPtr pScreen, XID context);
extern Bool DRIContextPrivDelete(pointer pResource, XID id);
extern Bool DRICreateDrawable(ScreenPtr pScreen,
- Drawable id,
+ ClientPtr client,
DrawablePtr pDrawable,
drm_drawable_t * hHWDrawable);
extern Bool DRIDestroyDrawable(ScreenPtr pScreen,
- Drawable id,
+ ClientPtr client,
DrawablePtr pDrawable);
extern Bool DRIDrawablePrivDelete(pointer pResource,
@@ -299,6 +299,8 @@ extern void DRIWindowExposures(WindowPtr pWin,
RegionPtr prgn,
RegionPtr bsreg);
+extern Bool DRIDestroyWindow(WindowPtr pWin);
+
extern void DRICopyWindow(WindowPtr pWin,
DDXPointRec ptOldOrg,
RegionPtr prgnSrc);
diff --git a/hw/xfree86/dri/dristruct.h b/hw/xfree86/dri/dristruct.h
index a3bac8556..5d981b820 100644
--- a/hw/xfree86/dri/dristruct.h
+++ b/hw/xfree86/dri/dristruct.h
@@ -99,6 +99,7 @@ typedef struct _DRIScreenPrivRec
DrawablePtr fullscreen; /* pointer to fullscreen drawable */
drm_clip_rect_t fullscreen_rect; /* fake rect for fullscreen mode */
DRIWrappedFuncsRec wrap;
+ DestroyWindowProcPtr DestroyWindow;
DrawablePtr DRIDrawables[SAREA_MAX_DRAWABLES];
DRIContextPrivPtr dummyCtxPriv; /* Pointer to dummy context */
Bool createDummyCtx;
diff --git a/hw/xfree86/dri/xf86dri.c b/hw/xfree86/dri/xf86dri.c
index 9690e8895..fdf0e9983 100644
--- a/hw/xfree86/dri/xf86dri.c
+++ b/hw/xfree86/dri/xf86dri.c
@@ -404,10 +404,8 @@ ProcXF86DRICreateDrawable(
if (rc != Success)
return rc;
- if (!DRICreateDrawable( screenInfo.screens[stuff->screen],
- (Drawable)stuff->drawable,
- pDrawable,
- (drm_drawable_t *)&rep.hHWDrawable)) {
+ if (!DRICreateDrawable(screenInfo.screens[stuff->screen], client,
+ pDrawable, (drm_drawable_t *)&rep.hHWDrawable)) {
return BadValue;
}
@@ -435,9 +433,8 @@ ProcXF86DRIDestroyDrawable(
if (rc != Success)
return rc;
- if (!DRIDestroyDrawable( screenInfo.screens[stuff->screen],
- (Drawable)stuff->drawable,
- pDrawable)) {
+ if (!DRIDestroyDrawable(screenInfo.screens[stuff->screen], client,
+ pDrawable)) {
return BadValue;
}