diff options
-rw-r--r-- | GL/glx/glxdri.c | 26 | ||||
-rw-r--r-- | GL/glx/glxext.c | 7 | ||||
-rw-r--r-- | GL/glx/glxserver.h | 2 | ||||
-rw-r--r-- | hw/xfree86/dri/dri.c | 139 | ||||
-rw-r--r-- | hw/xfree86/dri/dri.h | 6 | ||||
-rw-r--r-- | hw/xfree86/dri/dristruct.h | 1 | ||||
-rw-r--r-- | hw/xfree86/dri/xf86dri.c | 11 |
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; } |