xserver: Branch 'master' - 2 commits

Michel Daenzer daenzer at kemper.freedesktop.org
Tue Jul 10 00:03:53 PDT 2007


 GL/glx/glxcmds.c           |    2 
 GL/glx/glxdri.c            |   26 ++++----
 GL/glx/glxext.c            |    9 ++
 GL/glx/glxserver.h         |    2 
 hw/xfree86/dri/dri.c       |  139 +++++++++++++++++++++++++++++++--------------
 hw/xfree86/dri/dri.h       |    6 +
 hw/xfree86/dri/dristruct.h |    1 
 hw/xfree86/dri/xf86dri.c   |   11 +--
 8 files changed, 134 insertions(+), 62 deletions(-)

New commits:
diff-tree 161624a5a45808fd56141dc2c64be729944f03ed (from 4abd00dab7e648dab8172f6009371e4e63d0c521)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Tue Jul 10 09:02:40 2007 +0200

    GLX: Only build code dealing with GLXPixmap damage field when DRI is enabled.

diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c
index ed5c138..3038b13 100644
--- a/GL/glx/glxcmds.c
+++ b/GL/glx/glxcmds.c
@@ -1285,7 +1285,9 @@ int DoCreateGLXPixmap(__GLXclientState *
     pGlxPixmap->pGlxScreen = __glXgetActiveScreen(screenNum);
     pGlxPixmap->pScreen = pDraw->pScreen;
     pGlxPixmap->idExists = True;
+#ifdef XF86DRI
     pGlxPixmap->pDamage = NULL;
+#endif
     pGlxPixmap->refcnt = 0;
 
     pGlxPixmap->modes = modes;
diff --git a/GL/glx/glxext.c b/GL/glx/glxext.c
index b4f3105..b35175e 100644
--- a/GL/glx/glxext.c
+++ b/GL/glx/glxext.c
@@ -172,10 +172,12 @@ static int PixmapGone(__GLXpixmap *pGlxP
 
     pGlxPixmap->idExists = False;
     if (!pGlxPixmap->refcnt) {
+#ifdef XF86DRI
 	if (pGlxPixmap->pDamage) {
 	    DamageUnregister (pGlxPixmap->pDraw, pGlxPixmap->pDamage);
 	    DamageDestroy(pGlxPixmap->pDamage);
 	}
+#endif
 	/*
 	** The DestroyPixmap routine should decrement the refcount and free
 	** only if it's zero.
diff-tree 4abd00dab7e648dab8172f6009371e4e63d0c521 (from 5957aa6fdc580ccad4557eeefa0636ffad823f33)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Tue Jul 10 09:02:08 2007 +0200

    Make sure DRI drawables are cleaned up when client dies.
    
    The previous scheme didn't work when the client didn't create the core drawable,
    e.g. the root or composite overlay window. Use refcounting via special client
    resources to fix that.

diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c
index efa02f8..db564c0 100644
--- a/GL/glx/glxdri.c
+++ b/GL/glx/glxdri.c
@@ -758,9 +758,16 @@ static __DRIscreen *findScreen(__DRInati
 
 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, 
 	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,
 	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,
       *ppBackClipRects = NULL;
     }
 
-    return GL_TRUE;
+    return retval;
 }
 
 static int
diff --git a/GL/glx/glxext.c b/GL/glx/glxext.c
index c09120c..b4f3105 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 clien
 	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 fa09c15..b6b5592 100644
--- a/GL/glx/glxserver.h
+++ b/GL/glx/glxserver.h
@@ -110,6 +110,8 @@ void __glXScreenInitVisuals(__GLXscreen 
 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 2a53eae..6c640d8 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 pScre
 }
 
 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, Dra
 
 	    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, Dra
     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, Dr
 Bool
 DRIDrawablePrivDelete(pointer pResource, XID id)
 {
-    DrawablePtr		pDrawable = (DrawablePtr)pResource;
-    DRIScreenPrivPtr	pDRIPriv = DRI_SCREEN_PRIV(pDrawable->pScreen);
-    DRIDrawablePrivPtr	pDRIDrawablePriv;
-    WindowPtr		pWin;
+    WindowPtr pWin;
 
-    if (pDrawable->type == DRAWABLE_WINDOW) {
-	pWin = (WindowPtr)pDrawable;
-	pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
+    id = (XID)pResource;
+    pWin = LookupIDByType(id, RT_WINDOW);
 
-	if (pDRIDrawablePriv->drawableIndex != -1) {
-	    /* bump stamp to force outstanding 3D requests to resync */
-	    pDRIPriv->pSAREA->drawableTable[pDRIDrawablePriv->drawableIndex].stamp
-		= DRIDrawableValidationStamp++;
+    if (pWin) {
+	DRIDrawablePrivPtr pDRIDrwPriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
 
-	    /* release drawable table entry */
-	    pDRIPriv->DRIDrawables[pDRIDrawablePriv->drawableIndex] = NULL;
-	}
-
-	if (drmDestroyDrawable(pDRIPriv->drmFD,
-			       pDRIDrawablePriv->hwDrawable)) {
+	if (!pDRIDrwPriv)
 	    return FALSE;
-	}
-
-	xfree(pDRIDrawablePriv);
-	pWin->devPrivates[DRIWindowPrivIndex].ptr = NULL;
 
-	pDRIPriv->nrWindows--;
+	if (--pDRIDrwPriv->refCount == 0)
+	    DRIDrawablePrivDestroy(pWin);
 
-	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
     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 e49bb6f..c0da700 100644
--- a/hw/xfree86/dri/dri.h
+++ b/hw/xfree86/dri/dri.h
@@ -231,12 +231,12 @@ extern Bool DRIDestroyContext(ScreenPtr 
 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
                               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 a3bac85..5d981b8 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 9690e88..fdf0e99 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;
     }
 


More information about the xorg-commit mailing list