In order to ease resource tracking, disentangle DRI2Drawable XIDs from their references. This will be used in later patches to first limit the object leak from unnamed references created on behalf of Clients and then never destroy, and then to allow Clients to explicit manage their references to DRI2Drawables.
Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk> --- glx/glxdri2.c | 8 +-- hw/xfree86/dri2/dri2.c | 136 ++++++++++++++++++---------------------------- hw/xfree86/dri2/dri2.h | 11 ++-- hw/xfree86/dri2/dri2ext.c | 6 +- 4 files changed, 65 insertions(+), 96 deletions(-) diff --git a/glx/glxdri2.c b/glx/glxdri2.c index 9d37b32..1d5f9db 100644 --- a/glx/glxdri2.c +++ b/glx/glxdri2.c @@ -610,7 +610,7 @@ __glXDRIscreenCreateContext(__GLXscreen * baseScreen, } static void -__glXDRIinvalidateBuffers(DrawablePtr pDraw, void *priv, XID id) +__glXDRIinvalidateBuffers(DrawablePtr pDraw, void *priv) { __GLXDRIdrawable *private = priv; __GLXDRIscreen *screen = private->screen; @@ -649,9 +649,9 @@ __glXDRIscreenCreateDrawable(ClientPtr client, private->base.waitGL = __glXDRIdrawableWaitGL; private->base.waitX = __glXDRIdrawableWaitX; - ret = DRI2CreateDrawable2(client, pDraw, drawId, - __glXDRIinvalidateBuffers, private, - &private->dri2_id); + private->dri2_id = FakeClientID(client->index); + ret = DRI2CreateDrawable(client, pDraw, private->dri2_id, + __glXDRIinvalidateBuffers, private); if (cx != lastGLContext) { lastGLContext = cx; cx->makeCurrent(cx); diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index 1f33d16..af286e6 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -70,16 +70,16 @@ static DevPrivateKeyRec dri2PixmapPrivateKeyRec; static DevPrivateKeyRec dri2ClientPrivateKeyRec; -#define dri2ClientPrivateKey (&dri2ClientPrivateKeyRec) - -#define dri2ClientPrivate(_pClient) (dixLookupPrivate(&(_pClient)->devPrivates, \ - dri2ClientPrivateKey)) - typedef struct _DRI2Client { int prime_id; } DRI2ClientRec, *DRI2ClientPtr; -static RESTYPE dri2DrawableRes; +static DRI2ClientPtr dri2ClientPrivate(ClientPtr pClient) +{ + return dixLookupPrivate(&pClient->devPrivates, &dri2ClientPrivateKeyRec); +} + +static RESTYPE dri2DrawableRes, dri2ReferenceRes; typedef struct _DRI2Screen *DRI2ScreenPtr; @@ -207,6 +207,11 @@ DRI2AllocateDrawable(DrawablePtr pDraw) if (pPriv == NULL) return NULL; + if (!AddResource(pDraw->id, dri2DrawableRes, pPriv)) { + free(pPriv); + return NULL; + } + pPriv->dri2_screen = ds; pPriv->drawable = pDraw; pPriv->width = pDraw->width; @@ -273,49 +278,37 @@ DRI2SwapLimit(DrawablePtr pDraw, int swap_limit) } typedef struct DRI2DrawableRefRec { - XID id; - XID dri2_id; + XID pid; DRI2InvalidateProcPtr invalidate; void *priv; struct xorg_list link; } DRI2DrawableRefRec, *DRI2DrawableRefPtr; -static DRI2DrawableRefPtr -DRI2LookupDrawableRef(DRI2DrawablePtr pPriv, XID id) +int +DRI2CreateDrawable(ClientPtr client, DrawablePtr pDraw, XID pid, + DRI2InvalidateProcPtr invalidate, void *priv) { + DRI2DrawablePtr pPriv; DRI2DrawableRefPtr ref; - xorg_list_for_each_entry(ref, &pPriv->reference_list, link) { - if (ref->id == id) - return ref; - } - - return NULL; -} + pPriv = DRI2GetDrawable(pDraw); + if (pPriv == NULL) + pPriv = DRI2AllocateDrawable(pDraw); + if (pPriv == NULL) + return BadAlloc; -static int -DRI2AddDrawableRef(DRI2DrawablePtr pPriv, XID id, XID dri2_id, - DRI2InvalidateProcPtr invalidate, void *priv) -{ - DRI2DrawableRefPtr ref; + pPriv->prime_id = dri2ClientPrivate(client)->prime_id; ref = malloc(sizeof *ref); if (ref == NULL) return BadAlloc; - if (!AddResource(dri2_id, dri2DrawableRes, pPriv)) { + if (!AddResource(pid, dri2ReferenceRes, ref)) { free(ref); return BadAlloc; } - if (!DRI2LookupDrawableRef(pPriv, id)) - if (!AddResource(id, dri2DrawableRes, pPriv)) { - FreeResourceByType(dri2_id, dri2DrawableRes, TRUE); - free(ref); - return BadAlloc; - } - ref->id = id; - ref->dri2_id = dri2_id; + ref->pid = pid; ref->invalidate = invalidate; ref->priv = priv; xorg_list_add(&ref->link, &pPriv->reference_list); @@ -324,71 +317,32 @@ DRI2AddDrawableRef(DRI2DrawablePtr pPriv, XID id, XID dri2_id, } int -DRI2CreateDrawable2(ClientPtr client, DrawablePtr pDraw, XID id, - DRI2InvalidateProcPtr invalidate, void *priv, - XID *dri2_id_out) +DRI2DestroyDrawable(ClientPtr client, DrawablePtr pDraw, XID id) { - DRI2DrawablePtr pPriv; - DRI2ClientPtr dri2_client = dri2ClientPrivate(client); - XID dri2_id; - int rc; - - pPriv = DRI2GetDrawable(pDraw); - if (pPriv == NULL) - pPriv = DRI2AllocateDrawable(pDraw); - if (pPriv == NULL) - return BadAlloc; - - pPriv->prime_id = dri2_client->prime_id; - - dri2_id = FakeClientID(client->index); - rc = DRI2AddDrawableRef(pPriv, id, dri2_id, invalidate, priv); - if (rc != Success) - return rc; - - if (dri2_id_out) - *dri2_id_out = dri2_id; - + FreeResourceByType(id, dri2ReferenceRes, FALSE); return Success; } -int -DRI2CreateDrawable(ClientPtr client, DrawablePtr pDraw, XID id, - DRI2InvalidateProcPtr invalidate, void *priv) -{ - return DRI2CreateDrawable2(client, pDraw, id, invalidate, priv, NULL); -} - static int DRI2DrawableGone(void *p, XID id) { DRI2DrawablePtr pPriv = p; - DRI2DrawableRefPtr ref, next; WindowPtr pWin; PixmapPtr pPixmap; DrawablePtr pDraw; int i; - xorg_list_for_each_entry_safe(ref, next, &pPriv->reference_list, link) { - if (ref->dri2_id == id) { - xorg_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; - } + while (!xorg_list_is_empty(&pPriv->reference_list)) { + DRI2DrawableRefPtr ref; - if (ref->id == id) { - xorg_list_del(&ref->link); - FreeResourceByType(ref->dri2_id, dri2DrawableRes, TRUE); - free(ref); - } - } + ref = xorg_list_first_entry(&pPriv->reference_list, + DRI2DrawableRefRec, + link); + xorg_list_del(&ref->link); - if (!xorg_list_is_empty(&pPriv->reference_list)) - return Success; + FreeResourceByType(ref->pid, dri2ReferenceRes, TRUE); + free(ref); + } pDraw = pPriv->drawable; if (pDraw->type == DRAWABLE_WINDOW) { @@ -422,6 +376,20 @@ DRI2DrawableGone(void *p, XID id) return Success; } +static int +DRI2ReferenceGone(void *p, XID id) +{ + DRI2DrawableRefPtr ref = p; + DRI2DrawablePtr pPriv = ref->priv; + + xorg_list_del(&ref->link); + if (xorg_list_is_empty(&pPriv->reference_list)) + FreeResourceByType(pPriv->drawable->id, dri2DrawableRes, FALSE); + free(ref); + + return Success; +} + static DRI2BufferPtr create_buffer(DRI2ScreenPtr ds, DrawablePtr pDraw, unsigned int attachment, unsigned int format) @@ -691,7 +659,7 @@ DRI2InvalidateDrawable(DrawablePtr pDraw) pPriv->needInvalidate = FALSE; xorg_list_for_each_entry(ref, &pPriv->reference_list, link) - ref->invalidate(pDraw, ref->priv, ref->id); + ref->invalidate(pDraw, ref->priv); } /* @@ -1672,6 +1640,10 @@ DRI2ModuleSetup(void) if (!dri2DrawableRes) return FALSE; + dri2ReferenceRes = CreateNewResourceType(DRI2ReferenceGone, "DRI2Reference"); + if (!dri2ReferenceRes) + return FALSE; + return TRUE; } diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h index e76f7a8..7a89de2 100644 --- a/hw/xfree86/dri2/dri2.h +++ b/hw/xfree86/dri2/dri2.h @@ -161,7 +161,7 @@ typedef int (*DRI2ScheduleWaitMSCProcPtr) (ClientPtr client, CARD64 target_msc, CARD64 divisor, CARD64 remainder); -typedef void (*DRI2InvalidateProcPtr) (DrawablePtr pDraw, void *data, XID id); +typedef void (*DRI2InvalidateProcPtr) (DrawablePtr pDraw, void *data); /** * DRI2 calls this hook when ever swap_limit is going to be changed. Default @@ -274,16 +274,13 @@ extern _X_EXPORT Bool DRI2Authenticate(ClientPtr client, ScreenPtr pScreen, uint extern _X_EXPORT int DRI2CreateDrawable(ClientPtr client, DrawablePtr pDraw, - XID id, + XID pid, DRI2InvalidateProcPtr invalidate, void *priv); -extern _X_EXPORT int DRI2CreateDrawable2(ClientPtr client, +extern _X_EXPORT int DRI2DestroyDrawable(ClientPtr client, DrawablePtr pDraw, - XID id, - DRI2InvalidateProcPtr invalidate, - void *priv, - XID *dri2_id_out); + XID id); extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffers(DrawablePtr pDraw, int *width, diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c index 221ec53..5dae806 100644 --- a/hw/xfree86/dri2/dri2ext.c +++ b/hw/xfree86/dri2/dri2ext.c @@ -161,12 +161,12 @@ ProcDRI2Authenticate(ClientPtr client) } static void -DRI2InvalidateBuffersEvent(DrawablePtr pDraw, void *priv, XID id) +DRI2InvalidateBuffersEvent(DrawablePtr pDraw, void *priv) { ClientPtr client = priv; xDRI2InvalidateBuffers event = { .type = DRI2EventBase + DRI2_InvalidateBuffers, - .drawable = id + .drawable = pDraw->id, }; WriteEventsToClient(client, 1, (xEvent *) &event); @@ -185,7 +185,7 @@ ProcDRI2CreateDrawable(ClientPtr client) &pDrawable, &status)) return status; - status = DRI2CreateDrawable(client, pDrawable, stuff->drawable, + status = DRI2CreateDrawable(client, pDrawable, FakeClientID(client->index), DRI2InvalidateBuffersEvent, client); if (status != Success) return status; -- 2.1.4 _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel