Merge remote branch 'krh/dri2-resource-fixes'
This commit is contained in:
		
						commit
						3df22b293c
					
				| 
						 | 
				
			
			@ -589,6 +589,7 @@ FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
 | 
			
		|||
			      res->value, TypeNameString(res->type));
 | 
			
		||||
#endif		    		    
 | 
			
		||||
		*prev = res->next;
 | 
			
		||||
		clientTable[cid].elements--;
 | 
			
		||||
 | 
			
		||||
		CallResourceStateCallback(ResourceStateFreeing, res);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -734,12 +735,14 @@ FreeClientNeverRetainResources(ClientPtr client)
 | 
			
		|||
    ResourcePtr *resources;
 | 
			
		||||
    ResourcePtr this;
 | 
			
		||||
    ResourcePtr *prev;
 | 
			
		||||
    int j;
 | 
			
		||||
    int j, elements;
 | 
			
		||||
    int *eltptr;
 | 
			
		||||
 | 
			
		||||
    if (!client)
 | 
			
		||||
	return;
 | 
			
		||||
 | 
			
		||||
    resources = clientTable[client->index].resources;
 | 
			
		||||
    eltptr = &clientTable[client->index].elements;
 | 
			
		||||
    for (j=0; j < clientTable[client->index].buckets; j++) 
 | 
			
		||||
    {
 | 
			
		||||
	prev = &resources[j];
 | 
			
		||||
| 
						 | 
				
			
			@ -753,11 +756,15 @@ FreeClientNeverRetainResources(ClientPtr client)
 | 
			
		|||
			      this->value, TypeNameString(this->type));
 | 
			
		||||
#endif		    
 | 
			
		||||
		*prev = this->next;
 | 
			
		||||
		clientTable[client->index].elements--;
 | 
			
		||||
 | 
			
		||||
		CallResourceStateCallback(ResourceStateFreeing, this);
 | 
			
		||||
 | 
			
		||||
		elements = *eltptr;
 | 
			
		||||
		(*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
 | 
			
		||||
		xfree(this);
 | 
			
		||||
		if (*eltptr != elements)
 | 
			
		||||
		    prev = &resources[j]; /* prev may no longer be valid */
 | 
			
		||||
	    }
 | 
			
		||||
	    else
 | 
			
		||||
		prev = &this->next;
 | 
			
		||||
| 
						 | 
				
			
			@ -804,6 +811,7 @@ FreeClientResources(ClientPtr client)
 | 
			
		|||
			  this->value, TypeNameString(this->type));
 | 
			
		||||
#endif		    
 | 
			
		||||
	    *head = this->next;
 | 
			
		||||
	    clientTable[client->index].elements--;
 | 
			
		||||
 | 
			
		||||
	    CallResourceStateCallback(ResourceStateFreeing, this);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -512,8 +512,9 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client,
 | 
			
		|||
    if (!validGlxFBConfigForWindow(client, glxc->config, pDraw, error))
 | 
			
		||||
	return NULL;
 | 
			
		||||
 | 
			
		||||
    pGlxDraw = glxc->pGlxScreen->createDrawable(glxc->pGlxScreen,
 | 
			
		||||
						pDraw, GLX_DRAWABLE_WINDOW,
 | 
			
		||||
    pGlxDraw = glxc->pGlxScreen->createDrawable(client, glxc->pGlxScreen,
 | 
			
		||||
						pDraw, drawId,
 | 
			
		||||
						GLX_DRAWABLE_WINDOW,
 | 
			
		||||
						drawId, glxc->config);
 | 
			
		||||
 | 
			
		||||
    /* since we are creating the drawablePrivate, drawId should be new */
 | 
			
		||||
| 
						 | 
				
			
			@ -1104,15 +1105,17 @@ __glXDrawableRelease(__GLXdrawable *drawable)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static int 
 | 
			
		||||
DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config,
 | 
			
		||||
		    DrawablePtr pDraw, XID glxDrawableId, int type)
 | 
			
		||||
DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen,
 | 
			
		||||
		    __GLXconfig *config, DrawablePtr pDraw, XID drawableId,
 | 
			
		||||
		    XID glxDrawableId, int type)
 | 
			
		||||
{
 | 
			
		||||
    __GLXdrawable *pGlxDraw;
 | 
			
		||||
 | 
			
		||||
    if (pGlxScreen->pScreen != pDraw->pScreen)
 | 
			
		||||
	return BadMatch;
 | 
			
		||||
 | 
			
		||||
    pGlxDraw = pGlxScreen->createDrawable(pGlxScreen, pDraw, type,
 | 
			
		||||
    pGlxDraw = pGlxScreen->createDrawable(client, pGlxScreen, pDraw,
 | 
			
		||||
					  drawableId, type,
 | 
			
		||||
					  glxDrawableId, config);
 | 
			
		||||
    if (pGlxDraw == NULL)
 | 
			
		||||
	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
 | 
			
		||||
     * too.  That way we'll get a callback in DrawableGone and can
 | 
			
		||||
     * clean up properly when the drawable is destroyed. */
 | 
			
		||||
    if (pDraw->id != glxDrawableId &&
 | 
			
		||||
    if (drawableId != glxDrawableId &&
 | 
			
		||||
	!AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) {
 | 
			
		||||
	pGlxDraw->destroy (pGlxDraw);
 | 
			
		||||
	return BadAlloc;
 | 
			
		||||
| 
						 | 
				
			
			@ -1153,7 +1156,7 @@ DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config
 | 
			
		|||
	return BadPixmap;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw,
 | 
			
		||||
    err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, drawableId,
 | 
			
		||||
			      glxDrawableId, GLX_DRAWABLE_PIXMAP);
 | 
			
		||||
 | 
			
		||||
    return err;
 | 
			
		||||
| 
						 | 
				
			
			@ -1316,7 +1319,8 @@ DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
 | 
			
		|||
	return BadAlloc;
 | 
			
		||||
 | 
			
		||||
    return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable,
 | 
			
		||||
			       glxDrawableId, GLX_DRAWABLE_PBUFFER);
 | 
			
		||||
			       glxDrawableId, glxDrawableId,
 | 
			
		||||
			       GLX_DRAWABLE_PBUFFER);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc)
 | 
			
		||||
| 
						 | 
				
			
			@ -1439,7 +1443,8 @@ int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc)
 | 
			
		|||
	return err;
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -683,10 +683,12 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static __GLXdrawable *
 | 
			
		||||
__glXDRIscreenCreateDrawable(__GLXscreen *screen,
 | 
			
		||||
__glXDRIscreenCreateDrawable(ClientPtr client,
 | 
			
		||||
			     __GLXscreen *screen,
 | 
			
		||||
			     DrawablePtr pDraw,
 | 
			
		||||
			     int type,
 | 
			
		||||
			     XID drawId,
 | 
			
		||||
			     int type,
 | 
			
		||||
			     XID glxDrawId,
 | 
			
		||||
			     __GLXconfig *glxConfig)
 | 
			
		||||
{
 | 
			
		||||
    __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
 | 
			
		||||
| 
						 | 
				
			
			@ -700,7 +702,7 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
 | 
			
		|||
	return NULL;
 | 
			
		||||
 | 
			
		||||
    if (!__glXDrawableInit(&private->base, screen,
 | 
			
		||||
			   pDraw, type, drawId, glxConfig)) {
 | 
			
		||||
			   pDraw, type, glxDrawId, glxConfig)) {
 | 
			
		||||
        xfree(private);
 | 
			
		||||
	return NULL;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -430,10 +430,12 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static __GLXdrawable *
 | 
			
		||||
__glXDRIscreenCreateDrawable(__GLXscreen *screen,
 | 
			
		||||
__glXDRIscreenCreateDrawable(ClientPtr client,
 | 
			
		||||
			     __GLXscreen *screen,
 | 
			
		||||
			     DrawablePtr pDraw,
 | 
			
		||||
			     int type,
 | 
			
		||||
			     XID drawId,
 | 
			
		||||
			     int type,
 | 
			
		||||
			     XID glxDrawId,
 | 
			
		||||
			     __GLXconfig *glxConfig)
 | 
			
		||||
{
 | 
			
		||||
    __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
 | 
			
		||||
| 
						 | 
				
			
			@ -446,7 +448,7 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
 | 
			
		|||
 | 
			
		||||
    private->screen = driScreen;
 | 
			
		||||
    if (!__glXDrawableInit(&private->base, screen,
 | 
			
		||||
			   pDraw, type, drawId, glxConfig)) {
 | 
			
		||||
			   pDraw, type, glxDrawId, glxConfig)) {
 | 
			
		||||
        xfree(private);
 | 
			
		||||
	return NULL;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -457,7 +459,7 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
 | 
			
		|||
    private->base.waitGL	= __glXDRIdrawableWaitGL;
 | 
			
		||||
    private->base.waitX		= __glXDRIdrawableWaitX;
 | 
			
		||||
 | 
			
		||||
    if (DRI2CreateDrawable(pDraw)) {
 | 
			
		||||
    if (DRI2CreateDrawable(client, pDraw, drawId)) {
 | 
			
		||||
	    xfree(private);
 | 
			
		||||
	    return NULL;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -653,7 +655,7 @@ initializeExtensions(__GLXDRIscreen *screen)
 | 
			
		|||
 | 
			
		||||
#ifdef __DRI2_FLUSH
 | 
			
		||||
	if (strcmp(extensions[i]->name, __DRI2_FLUSH) == 0 &&
 | 
			
		||||
	    extensions[i]->version >= __DRI2_FLUSH_VERSION) {
 | 
			
		||||
	    extensions[i]->version >= 3) {
 | 
			
		||||
		screen->flush = (__DRI2flushExtension *) extensions[i];
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -713,11 +715,11 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
 | 
			
		|||
    
 | 
			
		||||
    for (i = 0; extensions[i]; i++) {
 | 
			
		||||
        if (strcmp(extensions[i]->name, __DRI_CORE) == 0 &&
 | 
			
		||||
	    extensions[i]->version >= __DRI_CORE_VERSION) {
 | 
			
		||||
	    extensions[i]->version >= 1) {
 | 
			
		||||
		screen->core = (const __DRIcoreExtension *) extensions[i];
 | 
			
		||||
	}
 | 
			
		||||
        if (strcmp(extensions[i]->name, __DRI_DRI2) == 0 &&
 | 
			
		||||
	    extensions[i]->version >= __DRI_DRI2_VERSION) {
 | 
			
		||||
	    extensions[i]->version >= 1) {
 | 
			
		||||
		screen->dri2 = (const __DRIdri2Extension *) extensions[i];
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -301,10 +301,12 @@ glxChangeGC(GCPtr gc, BITS32 mask, CARD32 val)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static __GLXdrawable *
 | 
			
		||||
__glXDRIscreenCreateDrawable(__GLXscreen *screen,
 | 
			
		||||
__glXDRIscreenCreateDrawable(ClientPtr client,
 | 
			
		||||
			     __GLXscreen *screen,
 | 
			
		||||
			     DrawablePtr pDraw,
 | 
			
		||||
			     int type,
 | 
			
		||||
			     XID drawId,
 | 
			
		||||
			     int type,
 | 
			
		||||
			     XID glxDrawId,
 | 
			
		||||
			     __GLXconfig *glxConfig)
 | 
			
		||||
{
 | 
			
		||||
    __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
 | 
			
		||||
| 
						 | 
				
			
			@ -319,7 +321,7 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
 | 
			
		|||
 | 
			
		||||
    private->screen = driScreen;
 | 
			
		||||
    if (!__glXDrawableInit(&private->base, screen,
 | 
			
		||||
			   pDraw, type, drawId, glxConfig)) {
 | 
			
		||||
			   pDraw, type, glxDrawId, glxConfig)) {
 | 
			
		||||
        xfree(private);
 | 
			
		||||
	return NULL;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -134,10 +134,12 @@ struct __GLXscreen {
 | 
			
		|||
				    __GLXconfig *modes,
 | 
			
		||||
				    __GLXcontext *shareContext);
 | 
			
		||||
 | 
			
		||||
    __GLXdrawable *(*createDrawable)(__GLXscreen *context,
 | 
			
		||||
    __GLXdrawable *(*createDrawable)(ClientPtr client,
 | 
			
		||||
				     __GLXscreen *context,
 | 
			
		||||
				     DrawablePtr pDraw,
 | 
			
		||||
				     int type,
 | 
			
		||||
				     XID drawId,
 | 
			
		||||
				     int type,
 | 
			
		||||
				     XID glxDrawId,
 | 
			
		||||
				     __GLXconfig *modes);
 | 
			
		||||
    int            (*swapInterval)  (__GLXdrawable *drawable,
 | 
			
		||||
				     int interval);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,6 +37,7 @@
 | 
			
		|||
#include <errno.h>
 | 
			
		||||
#include <xf86drm.h>
 | 
			
		||||
#include "xf86Module.h"
 | 
			
		||||
#include "list.h"
 | 
			
		||||
#include "scrnintstr.h"
 | 
			
		||||
#include "windowstr.h"
 | 
			
		||||
#include "dixstruct.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -50,12 +51,18 @@ CARD8 dri2_minor;
 | 
			
		|||
 | 
			
		||||
static int           dri2ScreenPrivateKeyIndex;
 | 
			
		||||
static DevPrivateKey dri2ScreenPrivateKey = &dri2ScreenPrivateKeyIndex;
 | 
			
		||||
static int dri2WindowPrivateKeyIndex;
 | 
			
		||||
static DevPrivateKey dri2WindowPrivateKey = &dri2WindowPrivateKeyIndex;
 | 
			
		||||
static int dri2PixmapPrivateKeyIndex;
 | 
			
		||||
static DevPrivateKey dri2PixmapPrivateKey = &dri2PixmapPrivateKeyIndex;
 | 
			
		||||
static RESTYPE       dri2DrawableRes;
 | 
			
		||||
 | 
			
		||||
typedef struct _DRI2Screen *DRI2ScreenPtr;
 | 
			
		||||
 | 
			
		||||
typedef struct _DRI2Drawable {
 | 
			
		||||
    DRI2ScreenPtr        dri2_screen;
 | 
			
		||||
    DrawablePtr		 drawable;
 | 
			
		||||
    struct list		 reference_list;
 | 
			
		||||
    int			 width;
 | 
			
		||||
    int			 height;
 | 
			
		||||
    DRI2BufferPtr	*buffers;
 | 
			
		||||
| 
						 | 
				
			
			@ -74,6 +81,7 @@ typedef struct _DRI2Drawable {
 | 
			
		|||
 | 
			
		||||
typedef struct _DRI2Screen {
 | 
			
		||||
    ScreenPtr			 screen;
 | 
			
		||||
    int				 refcnt;
 | 
			
		||||
    unsigned int		 numDrivers;
 | 
			
		||||
    const char			**driverNames;
 | 
			
		||||
    const char			*deviceName;
 | 
			
		||||
| 
						 | 
				
			
			@ -99,35 +107,33 @@ DRI2GetScreen(ScreenPtr pScreen)
 | 
			
		|||
static DRI2DrawablePtr
 | 
			
		||||
DRI2GetDrawable(DrawablePtr pDraw)
 | 
			
		||||
{
 | 
			
		||||
    DRI2DrawablePtr pPriv;
 | 
			
		||||
    int rc;
 | 
			
		||||
    WindowPtr pWin;
 | 
			
		||||
    PixmapPtr pPixmap;
 | 
			
		||||
 | 
			
		||||
    rc = dixLookupResourceByType((pointer *) &pPriv, pDraw->id,
 | 
			
		||||
				 dri2DrawableRes, NULL, DixReadAccess);
 | 
			
		||||
    if (rc != Success)
 | 
			
		||||
	return NULL;
 | 
			
		||||
 | 
			
		||||
    return pPriv;
 | 
			
		||||
    if (pDraw->type == DRAWABLE_WINDOW) {
 | 
			
		||||
	pWin = (WindowPtr) pDraw;
 | 
			
		||||
	return dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey);
 | 
			
		||||
    } else {
 | 
			
		||||
	pPixmap = (PixmapPtr) pDraw;
 | 
			
		||||
	return dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
DRI2CreateDrawable(DrawablePtr pDraw)
 | 
			
		||||
static DRI2DrawablePtr
 | 
			
		||||
DRI2AllocateDrawable(DrawablePtr pDraw)
 | 
			
		||||
{
 | 
			
		||||
    DRI2ScreenPtr   ds = DRI2GetScreen(pDraw->pScreen);
 | 
			
		||||
    DRI2DrawablePtr pPriv;
 | 
			
		||||
    CARD64          ust;
 | 
			
		||||
    int		    rc;
 | 
			
		||||
 | 
			
		||||
    rc = dixLookupResourceByType((pointer *) &pPriv, pDraw->id,
 | 
			
		||||
				 dri2DrawableRes, NULL, DixReadAccess);
 | 
			
		||||
    if (rc == Success || rc != BadValue)
 | 
			
		||||
	return rc;
 | 
			
		||||
    WindowPtr pWin;
 | 
			
		||||
    PixmapPtr pPixmap;
 | 
			
		||||
 | 
			
		||||
    pPriv = xalloc(sizeof *pPriv);
 | 
			
		||||
    if (pPriv == NULL)
 | 
			
		||||
	return BadAlloc;
 | 
			
		||||
	return NULL;
 | 
			
		||||
 | 
			
		||||
    pPriv->dri2_screen = ds;
 | 
			
		||||
    pPriv->drawable = pDraw;
 | 
			
		||||
    pPriv->width = pDraw->width;
 | 
			
		||||
    pPriv->height = pDraw->height;
 | 
			
		||||
    pPriv->buffers = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -145,9 +151,77 @@ DRI2CreateDrawable(DrawablePtr pDraw)
 | 
			
		|||
    pPriv->swap_limit = 1; /* default to double buffering */
 | 
			
		||||
    pPriv->last_swap_msc = 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;
 | 
			
		||||
	
 | 
			
		||||
    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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -156,13 +230,45 @@ static int DRI2DrawableGone(pointer p, XID id)
 | 
			
		|||
{
 | 
			
		||||
    DRI2DrawablePtr pPriv = p;
 | 
			
		||||
    DRI2ScreenPtr   ds = pPriv->dri2_screen;
 | 
			
		||||
    DrawablePtr     root;
 | 
			
		||||
    DRI2DrawableRefPtr ref, next;
 | 
			
		||||
    WindowPtr pWin;
 | 
			
		||||
    PixmapPtr pPixmap;
 | 
			
		||||
    DrawablePtr pDraw;
 | 
			
		||||
    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) {
 | 
			
		||||
	for (i = 0; i < pPriv->bufferCount; i++)
 | 
			
		||||
	    (*ds->DestroyBuffer)(root, pPriv->buffers[i]);
 | 
			
		||||
	    (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
 | 
			
		||||
 | 
			
		||||
	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 int DRI2CreateDrawable(DrawablePtr pDraw);
 | 
			
		||||
extern _X_EXPORT int DRI2CreateDrawable(ClientPtr client,
 | 
			
		||||
					DrawablePtr pDraw, XID id);
 | 
			
		||||
 | 
			
		||||
extern _X_EXPORT void DRI2DestroyDrawable(DrawablePtr pDraw);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -167,7 +167,7 @@ ProcDRI2CreateDrawable(ClientPtr client)
 | 
			
		|||
		       &pDrawable, &status))
 | 
			
		||||
	return status;
 | 
			
		||||
 | 
			
		||||
    status = DRI2CreateDrawable(pDrawable);
 | 
			
		||||
    status = DRI2CreateDrawable(client, pDrawable, stuff->drawable);
 | 
			
		||||
    if (status != Success)
 | 
			
		||||
	return status;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -94,4 +94,10 @@ list_is_empty(struct list *head)
 | 
			
		|||
	 &pos->member != (head);					\
 | 
			
		||||
	 pos = __container_of(pos->member.next, pos, member))
 | 
			
		||||
 | 
			
		||||
#define list_for_each_entry_safe(pos, next, head, member)		\
 | 
			
		||||
    for (pos = __container_of((head)->next, pos, member),		\
 | 
			
		||||
	 next = __container_of(pos->member.next, pos, member);		\
 | 
			
		||||
	 &pos->member != (head);					\
 | 
			
		||||
	 pos = next, next = __container_of(next->member.next, next, member))
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue