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,10 +151,78 @@ 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