dri2: Take an XID for tracking the DRI2 drawable
Some pixmaps (window pixmaps and scratch pixmaps) don't have the drawable->id set and thus DRI2 gets confused when using that field for looking up the DRI2 drawable. Go back to using privates for getting at the DRI2 drawable from a DrawablePtr. We need to keep the resource tracking in place so we can remove the DRI2 drawable when the X resource it was created for goes away. Additionally, we also now track the DRI2 drawable using a client XID so we can reclaim the DRI2 drawable even if the client goes before the drawable and doesn't destroy the DRI2 drawable. Tested-by: Owen W. Taylor <otaylor@fishsoup.net> Signed-off-by: Kristian Høgsberg <krh@bitplanet.net>
This commit is contained in:
		
							parent
							
								
									32381363cd
								
							
						
					
					
						commit
						9de0e31746
					
				|  | @ -512,8 +512,9 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client, | ||||||
|     if (!validGlxFBConfigForWindow(client, glxc->config, pDraw, error)) |     if (!validGlxFBConfigForWindow(client, glxc->config, pDraw, error)) | ||||||
| 	return NULL; | 	return NULL; | ||||||
| 
 | 
 | ||||||
|     pGlxDraw = glxc->pGlxScreen->createDrawable(glxc->pGlxScreen, |     pGlxDraw = glxc->pGlxScreen->createDrawable(client, glxc->pGlxScreen, | ||||||
| 						pDraw, GLX_DRAWABLE_WINDOW, | 						pDraw, drawId, | ||||||
|  | 						GLX_DRAWABLE_WINDOW, | ||||||
| 						drawId, glxc->config); | 						drawId, glxc->config); | ||||||
| 
 | 
 | ||||||
|     /* since we are creating the drawablePrivate, drawId should be new */ |     /* since we are creating the drawablePrivate, drawId should be new */ | ||||||
|  | @ -1104,15 +1105,17 @@ __glXDrawableRelease(__GLXdrawable *drawable) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int  | static int  | ||||||
| DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config, | DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, | ||||||
| 		    DrawablePtr pDraw, XID glxDrawableId, int type) | 		    __GLXconfig *config, DrawablePtr pDraw, XID drawableId, | ||||||
|  | 		    XID glxDrawableId, int type) | ||||||
| { | { | ||||||
|     __GLXdrawable *pGlxDraw; |     __GLXdrawable *pGlxDraw; | ||||||
| 
 | 
 | ||||||
|     if (pGlxScreen->pScreen != pDraw->pScreen) |     if (pGlxScreen->pScreen != pDraw->pScreen) | ||||||
| 	return BadMatch; | 	return BadMatch; | ||||||
| 
 | 
 | ||||||
|     pGlxDraw = pGlxScreen->createDrawable(pGlxScreen, pDraw, type, |     pGlxDraw = pGlxScreen->createDrawable(client, pGlxScreen, pDraw, | ||||||
|  | 					  drawableId, type, | ||||||
| 					  glxDrawableId, config); | 					  glxDrawableId, config); | ||||||
|     if (pGlxDraw == NULL) |     if (pGlxDraw == NULL) | ||||||
| 	return BadAlloc; | 	return BadAlloc; | ||||||
|  | @ -1125,7 +1128,7 @@ DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *conf | ||||||
|     /* Add the glx drawable under the XID of the underlying X drawable
 |     /* Add the glx drawable under the XID of the underlying X drawable
 | ||||||
|      * too.  That way we'll get a callback in DrawableGone and can |      * too.  That way we'll get a callback in DrawableGone and can | ||||||
|      * clean up properly when the drawable is destroyed. */ |      * clean up properly when the drawable is destroyed. */ | ||||||
|     if (pDraw->id != glxDrawableId && |     if (drawableId != glxDrawableId && | ||||||
| 	!AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) { | 	!AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) { | ||||||
| 	pGlxDraw->destroy (pGlxDraw); | 	pGlxDraw->destroy (pGlxDraw); | ||||||
| 	return BadAlloc; | 	return BadAlloc; | ||||||
|  | @ -1153,7 +1156,7 @@ DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config | ||||||
| 	return BadPixmap; | 	return BadPixmap; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, |     err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, drawableId, | ||||||
| 			      glxDrawableId, GLX_DRAWABLE_PIXMAP); | 			      glxDrawableId, GLX_DRAWABLE_PIXMAP); | ||||||
| 
 | 
 | ||||||
|     return err; |     return err; | ||||||
|  | @ -1316,7 +1319,8 @@ DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId, | ||||||
| 	return BadAlloc; | 	return BadAlloc; | ||||||
| 
 | 
 | ||||||
|     return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable, |     return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable, | ||||||
| 			       glxDrawableId, GLX_DRAWABLE_PBUFFER); | 			       glxDrawableId, glxDrawableId, | ||||||
|  | 			       GLX_DRAWABLE_PBUFFER); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc) | int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc) | ||||||
|  | @ -1439,7 +1443,8 @@ int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc) | ||||||
| 	return err; | 	return err; | ||||||
| 
 | 
 | ||||||
|     return DoCreateGLXDrawable(client, pGlxScreen, config, |     return DoCreateGLXDrawable(client, pGlxScreen, config, | ||||||
| 			       pDraw, req->glxwindow, GLX_DRAWABLE_WINDOW); | 			       pDraw, req->window, | ||||||
|  | 			       req->glxwindow, GLX_DRAWABLE_WINDOW); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int __glXDisp_DestroyWindow(__GLXclientState *cl, GLbyte *pc) | int __glXDisp_DestroyWindow(__GLXclientState *cl, GLbyte *pc) | ||||||
|  |  | ||||||
|  | @ -683,10 +683,12 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static __GLXdrawable * | static __GLXdrawable * | ||||||
| __glXDRIscreenCreateDrawable(__GLXscreen *screen, | __glXDRIscreenCreateDrawable(ClientPtr client, | ||||||
|  | 			     __GLXscreen *screen, | ||||||
| 			     DrawablePtr pDraw, | 			     DrawablePtr pDraw, | ||||||
| 			     int type, |  | ||||||
| 			     XID drawId, | 			     XID drawId, | ||||||
|  | 			     int type, | ||||||
|  | 			     XID glxDrawId, | ||||||
| 			     __GLXconfig *glxConfig) | 			     __GLXconfig *glxConfig) | ||||||
| { | { | ||||||
|     __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen; |     __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen; | ||||||
|  | @ -700,7 +702,7 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen, | ||||||
| 	return NULL; | 	return NULL; | ||||||
| 
 | 
 | ||||||
|     if (!__glXDrawableInit(&private->base, screen, |     if (!__glXDrawableInit(&private->base, screen, | ||||||
| 			   pDraw, type, drawId, glxConfig)) { | 			   pDraw, type, glxDrawId, glxConfig)) { | ||||||
|         xfree(private); |         xfree(private); | ||||||
| 	return NULL; | 	return NULL; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -430,10 +430,12 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static __GLXdrawable * | static __GLXdrawable * | ||||||
| __glXDRIscreenCreateDrawable(__GLXscreen *screen, | __glXDRIscreenCreateDrawable(ClientPtr client, | ||||||
|  | 			     __GLXscreen *screen, | ||||||
| 			     DrawablePtr pDraw, | 			     DrawablePtr pDraw, | ||||||
| 			     int type, |  | ||||||
| 			     XID drawId, | 			     XID drawId, | ||||||
|  | 			     int type, | ||||||
|  | 			     XID glxDrawId, | ||||||
| 			     __GLXconfig *glxConfig) | 			     __GLXconfig *glxConfig) | ||||||
| { | { | ||||||
|     __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen; |     __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen; | ||||||
|  | @ -446,7 +448,7 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen, | ||||||
| 
 | 
 | ||||||
|     private->screen = driScreen; |     private->screen = driScreen; | ||||||
|     if (!__glXDrawableInit(&private->base, screen, |     if (!__glXDrawableInit(&private->base, screen, | ||||||
| 			   pDraw, type, drawId, glxConfig)) { | 			   pDraw, type, glxDrawId, glxConfig)) { | ||||||
|         xfree(private); |         xfree(private); | ||||||
| 	return NULL; | 	return NULL; | ||||||
|     } |     } | ||||||
|  | @ -457,7 +459,7 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen, | ||||||
|     private->base.waitGL	= __glXDRIdrawableWaitGL; |     private->base.waitGL	= __glXDRIdrawableWaitGL; | ||||||
|     private->base.waitX		= __glXDRIdrawableWaitX; |     private->base.waitX		= __glXDRIdrawableWaitX; | ||||||
| 
 | 
 | ||||||
|     if (DRI2CreateDrawable(pDraw)) { |     if (DRI2CreateDrawable(client, pDraw, drawId)) { | ||||||
| 	    xfree(private); | 	    xfree(private); | ||||||
| 	    return NULL; | 	    return NULL; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -301,10 +301,12 @@ glxChangeGC(GCPtr gc, BITS32 mask, CARD32 val) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static __GLXdrawable * | static __GLXdrawable * | ||||||
| __glXDRIscreenCreateDrawable(__GLXscreen *screen, | __glXDRIscreenCreateDrawable(ClientPtr client, | ||||||
|  | 			     __GLXscreen *screen, | ||||||
| 			     DrawablePtr pDraw, | 			     DrawablePtr pDraw, | ||||||
| 			     int type, |  | ||||||
| 			     XID drawId, | 			     XID drawId, | ||||||
|  | 			     int type, | ||||||
|  | 			     XID glxDrawId, | ||||||
| 			     __GLXconfig *glxConfig) | 			     __GLXconfig *glxConfig) | ||||||
| { | { | ||||||
|     __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen; |     __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen; | ||||||
|  | @ -319,7 +321,7 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen, | ||||||
| 
 | 
 | ||||||
|     private->screen = driScreen; |     private->screen = driScreen; | ||||||
|     if (!__glXDrawableInit(&private->base, screen, |     if (!__glXDrawableInit(&private->base, screen, | ||||||
| 			   pDraw, type, drawId, glxConfig)) { | 			   pDraw, type, glxDrawId, glxConfig)) { | ||||||
|         xfree(private); |         xfree(private); | ||||||
| 	return NULL; | 	return NULL; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -134,10 +134,12 @@ struct __GLXscreen { | ||||||
| 				    __GLXconfig *modes, | 				    __GLXconfig *modes, | ||||||
| 				    __GLXcontext *shareContext); | 				    __GLXcontext *shareContext); | ||||||
| 
 | 
 | ||||||
|     __GLXdrawable *(*createDrawable)(__GLXscreen *context, |     __GLXdrawable *(*createDrawable)(ClientPtr client, | ||||||
|  | 				     __GLXscreen *context, | ||||||
| 				     DrawablePtr pDraw, | 				     DrawablePtr pDraw, | ||||||
| 				     int type, |  | ||||||
| 				     XID drawId, | 				     XID drawId, | ||||||
|  | 				     int type, | ||||||
|  | 				     XID glxDrawId, | ||||||
| 				     __GLXconfig *modes); | 				     __GLXconfig *modes); | ||||||
|     int            (*swapInterval)  (__GLXdrawable *drawable, |     int            (*swapInterval)  (__GLXdrawable *drawable, | ||||||
| 				     int interval); | 				     int interval); | ||||||
|  |  | ||||||
|  | @ -37,6 +37,7 @@ | ||||||
| #include <errno.h> | #include <errno.h> | ||||||
| #include <xf86drm.h> | #include <xf86drm.h> | ||||||
| #include "xf86Module.h" | #include "xf86Module.h" | ||||||
|  | #include "list.h" | ||||||
| #include "scrnintstr.h" | #include "scrnintstr.h" | ||||||
| #include "windowstr.h" | #include "windowstr.h" | ||||||
| #include "dixstruct.h" | #include "dixstruct.h" | ||||||
|  | @ -50,12 +51,18 @@ CARD8 dri2_minor; | ||||||
| 
 | 
 | ||||||
| static int           dri2ScreenPrivateKeyIndex; | static int           dri2ScreenPrivateKeyIndex; | ||||||
| static DevPrivateKey dri2ScreenPrivateKey = &dri2ScreenPrivateKeyIndex; | static DevPrivateKey dri2ScreenPrivateKey = &dri2ScreenPrivateKeyIndex; | ||||||
|  | static int dri2WindowPrivateKeyIndex; | ||||||
|  | static DevPrivateKey dri2WindowPrivateKey = &dri2WindowPrivateKeyIndex; | ||||||
|  | static int dri2PixmapPrivateKeyIndex; | ||||||
|  | static DevPrivateKey dri2PixmapPrivateKey = &dri2PixmapPrivateKeyIndex; | ||||||
| static RESTYPE       dri2DrawableRes; | static RESTYPE       dri2DrawableRes; | ||||||
| 
 | 
 | ||||||
| typedef struct _DRI2Screen *DRI2ScreenPtr; | typedef struct _DRI2Screen *DRI2ScreenPtr; | ||||||
| 
 | 
 | ||||||
| typedef struct _DRI2Drawable { | typedef struct _DRI2Drawable { | ||||||
|     DRI2ScreenPtr        dri2_screen; |     DRI2ScreenPtr        dri2_screen; | ||||||
|  |     DrawablePtr		 drawable; | ||||||
|  |     struct list		 reference_list; | ||||||
|     int			 width; |     int			 width; | ||||||
|     int			 height; |     int			 height; | ||||||
|     DRI2BufferPtr	*buffers; |     DRI2BufferPtr	*buffers; | ||||||
|  | @ -74,6 +81,7 @@ typedef struct _DRI2Drawable { | ||||||
| 
 | 
 | ||||||
| typedef struct _DRI2Screen { | typedef struct _DRI2Screen { | ||||||
|     ScreenPtr			 screen; |     ScreenPtr			 screen; | ||||||
|  |     int				 refcnt; | ||||||
|     unsigned int		 numDrivers; |     unsigned int		 numDrivers; | ||||||
|     const char			**driverNames; |     const char			**driverNames; | ||||||
|     const char			*deviceName; |     const char			*deviceName; | ||||||
|  | @ -99,35 +107,33 @@ DRI2GetScreen(ScreenPtr pScreen) | ||||||
| static DRI2DrawablePtr | static DRI2DrawablePtr | ||||||
| DRI2GetDrawable(DrawablePtr pDraw) | DRI2GetDrawable(DrawablePtr pDraw) | ||||||
| { | { | ||||||
|     DRI2DrawablePtr pPriv; |     WindowPtr pWin; | ||||||
|     int rc; |     PixmapPtr pPixmap; | ||||||
| 
 | 
 | ||||||
|     rc = dixLookupResourceByType((pointer *) &pPriv, pDraw->id, |     if (pDraw->type == DRAWABLE_WINDOW) { | ||||||
| 				 dri2DrawableRes, NULL, DixReadAccess); | 	pWin = (WindowPtr) pDraw; | ||||||
|     if (rc != Success) | 	return dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey); | ||||||
| 	return NULL; |     } else { | ||||||
| 
 | 	pPixmap = (PixmapPtr) pDraw; | ||||||
|     return pPriv; | 	return dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | static DRI2DrawablePtr | ||||||
| DRI2CreateDrawable(DrawablePtr pDraw) | DRI2AllocateDrawable(DrawablePtr pDraw) | ||||||
| { | { | ||||||
|     DRI2ScreenPtr   ds = DRI2GetScreen(pDraw->pScreen); |     DRI2ScreenPtr   ds = DRI2GetScreen(pDraw->pScreen); | ||||||
|     DRI2DrawablePtr pPriv; |     DRI2DrawablePtr pPriv; | ||||||
|     CARD64          ust; |     CARD64          ust; | ||||||
|     int		    rc; |     WindowPtr pWin; | ||||||
| 
 |     PixmapPtr pPixmap; | ||||||
|     rc = dixLookupResourceByType((pointer *) &pPriv, pDraw->id, |  | ||||||
| 				 dri2DrawableRes, NULL, DixReadAccess); |  | ||||||
|     if (rc == Success || rc != BadValue) |  | ||||||
| 	return rc; |  | ||||||
| 
 | 
 | ||||||
|     pPriv = xalloc(sizeof *pPriv); |     pPriv = xalloc(sizeof *pPriv); | ||||||
|     if (pPriv == NULL) |     if (pPriv == NULL) | ||||||
| 	return BadAlloc; | 	return NULL; | ||||||
| 
 | 
 | ||||||
|     pPriv->dri2_screen = ds; |     pPriv->dri2_screen = ds; | ||||||
|  |     pPriv->drawable = pDraw; | ||||||
|     pPriv->width = pDraw->width; |     pPriv->width = pDraw->width; | ||||||
|     pPriv->height = pDraw->height; |     pPriv->height = pDraw->height; | ||||||
|     pPriv->buffers = NULL; |     pPriv->buffers = NULL; | ||||||
|  | @ -145,9 +151,77 @@ DRI2CreateDrawable(DrawablePtr pDraw) | ||||||
|     pPriv->swap_limit = 1; /* default to double buffering */ |     pPriv->swap_limit = 1; /* default to double buffering */ | ||||||
|     pPriv->last_swap_msc = 0; |     pPriv->last_swap_msc = 0; | ||||||
|     pPriv->last_swap_ust = 0; |     pPriv->last_swap_ust = 0; | ||||||
|  |     list_init(&pPriv->reference_list); | ||||||
| 
 | 
 | ||||||
|     if (!AddResource(pDraw->id, dri2DrawableRes, pPriv)) |     if (pDraw->type == DRAWABLE_WINDOW) { | ||||||
|  | 	pWin = (WindowPtr) pDraw; | ||||||
|  | 	dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, pPriv); | ||||||
|  |     } else { | ||||||
|  | 	pPixmap = (PixmapPtr) pDraw; | ||||||
|  | 	dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, pPriv); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return pPriv; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | typedef struct DRI2DrawableRefRec { | ||||||
|  |     XID id; | ||||||
|  |     XID dri2_id; | ||||||
|  |     struct list link; | ||||||
|  | } DRI2DrawableRefRec, *DRI2DrawableRefPtr; | ||||||
|  | 
 | ||||||
|  | static DRI2DrawableRefPtr | ||||||
|  | DRI2LookupDrawableRef(DRI2DrawablePtr pPriv, XID id) | ||||||
|  | { | ||||||
|  |     DRI2DrawableRefPtr ref; | ||||||
|  | 
 | ||||||
|  |     list_for_each_entry(ref, &pPriv->reference_list, link) { | ||||||
|  | 	if (ref->id == id) | ||||||
|  | 	    return ref; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     return NULL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | DRI2AddDrawableRef(DRI2DrawablePtr pPriv, XID id, XID dri2_id) | ||||||
|  | { | ||||||
|  |     DRI2DrawableRefPtr ref; | ||||||
|  | 
 | ||||||
|  |     ref = malloc(sizeof *ref); | ||||||
|  |     if (ref == NULL) | ||||||
| 	return BadAlloc; | 	return BadAlloc; | ||||||
|  | 	 | ||||||
|  |     if (!AddResource(dri2_id, dri2DrawableRes, pPriv)) | ||||||
|  | 	return BadAlloc; | ||||||
|  |     if (!DRI2LookupDrawableRef(pPriv, id)) | ||||||
|  | 	if (!AddResource(id, dri2DrawableRes, pPriv)) | ||||||
|  | 	    return BadAlloc; | ||||||
|  | 
 | ||||||
|  |     ref->id = id; | ||||||
|  |     ref->dri2_id = dri2_id;  | ||||||
|  |     list_add(&ref->link, &pPriv->reference_list); | ||||||
|  | 
 | ||||||
|  |     return Success; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | DRI2CreateDrawable(ClientPtr client, DrawablePtr pDraw, XID id) | ||||||
|  | { | ||||||
|  |     DRI2DrawablePtr pPriv; | ||||||
|  |     XID dri2_id; | ||||||
|  |     int rc; | ||||||
|  | 
 | ||||||
|  |     pPriv = DRI2GetDrawable(pDraw); | ||||||
|  |     if (pPriv == NULL) | ||||||
|  | 	pPriv = DRI2AllocateDrawable(pDraw); | ||||||
|  |     if (pPriv == NULL) | ||||||
|  | 	return BadAlloc; | ||||||
|  |      | ||||||
|  |     dri2_id = FakeClientID(client->index); | ||||||
|  |     rc = DRI2AddDrawableRef(pPriv, id, dri2_id); | ||||||
|  |     if (rc != Success) | ||||||
|  | 	return rc; | ||||||
| 
 | 
 | ||||||
|     return Success; |     return Success; | ||||||
| } | } | ||||||
|  | @ -156,13 +230,45 @@ static int DRI2DrawableGone(pointer p, XID id) | ||||||
| { | { | ||||||
|     DRI2DrawablePtr pPriv = p; |     DRI2DrawablePtr pPriv = p; | ||||||
|     DRI2ScreenPtr   ds = pPriv->dri2_screen; |     DRI2ScreenPtr   ds = pPriv->dri2_screen; | ||||||
|     DrawablePtr     root; |     DRI2DrawableRefPtr ref, next; | ||||||
|  |     WindowPtr pWin; | ||||||
|  |     PixmapPtr pPixmap; | ||||||
|  |     DrawablePtr pDraw; | ||||||
|     int i; |     int i; | ||||||
| 
 | 
 | ||||||
|     root = &WindowTable[ds->screen->myNum]->drawable; |     list_for_each_entry_safe(ref, next, &pPriv->reference_list, link) { | ||||||
|  | 	if (ref->dri2_id == id) { | ||||||
|  | 	    list_del(&ref->link); | ||||||
|  | 	    /* If this was the last ref under this X drawable XID,
 | ||||||
|  | 	     * unregister the X drawable resource. */ | ||||||
|  | 	    if (!DRI2LookupDrawableRef(pPriv, ref->id)) | ||||||
|  | 		FreeResourceByType(ref->id, dri2DrawableRes, TRUE); | ||||||
|  | 	    free(ref); | ||||||
|  | 	    break; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (ref->id == id) { | ||||||
|  | 	    list_del(&ref->link); | ||||||
|  | 	    FreeResourceByType(ref->dri2_id, dri2DrawableRes, TRUE); | ||||||
|  | 	    free(ref); | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (!list_is_empty(&pPriv->reference_list)) | ||||||
|  | 	return Success; | ||||||
|  | 
 | ||||||
|  |     pDraw = pPriv->drawable; | ||||||
|  |     if (pDraw->type == DRAWABLE_WINDOW) { | ||||||
|  | 	pWin = (WindowPtr) pDraw; | ||||||
|  | 	dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL); | ||||||
|  |     } else { | ||||||
|  | 	pPixmap = (PixmapPtr) pDraw; | ||||||
|  | 	dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, NULL); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     if (pPriv->buffers != NULL) { |     if (pPriv->buffers != NULL) { | ||||||
| 	for (i = 0; i < pPriv->bufferCount; i++) | 	for (i = 0; i < pPriv->bufferCount; i++) | ||||||
| 	    (*ds->DestroyBuffer)(root, pPriv->buffers[i]); | 	    (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]); | ||||||
| 
 | 
 | ||||||
| 	xfree(pPriv->buffers); | 	xfree(pPriv->buffers); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -198,7 +198,8 @@ extern _X_EXPORT Bool DRI2Connect(ScreenPtr pScreen, | ||||||
| 
 | 
 | ||||||
| extern _X_EXPORT Bool DRI2Authenticate(ScreenPtr pScreen, drm_magic_t magic); | extern _X_EXPORT Bool DRI2Authenticate(ScreenPtr pScreen, drm_magic_t magic); | ||||||
| 
 | 
 | ||||||
| extern _X_EXPORT int DRI2CreateDrawable(DrawablePtr pDraw); | extern _X_EXPORT int DRI2CreateDrawable(ClientPtr client, | ||||||
|  | 					DrawablePtr pDraw, XID id); | ||||||
| 
 | 
 | ||||||
| extern _X_EXPORT void DRI2DestroyDrawable(DrawablePtr pDraw); | extern _X_EXPORT void DRI2DestroyDrawable(DrawablePtr pDraw); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -167,7 +167,7 @@ ProcDRI2CreateDrawable(ClientPtr client) | ||||||
| 		       &pDrawable, &status)) | 		       &pDrawable, &status)) | ||||||
| 	return status; | 	return status; | ||||||
| 
 | 
 | ||||||
|     status = DRI2CreateDrawable(pDrawable); |     status = DRI2CreateDrawable(client, pDrawable, stuff->drawable); | ||||||
|     if (status != Success) |     if (status != Success) | ||||||
| 	return status; | 	return status; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue