[PATCH 2/3] dri2: Split resource tracking for DRI2Drawable and references to them

Chris Wilson chris at chris-wilson.co.uk
Sun Feb 22 06:41:42 PST 2015


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 <chris at chris-wilson.co.uk>
---
 glx/glxdri2.c             |  10 ++--
 hw/xfree86/dri2/dri2.c    | 136 ++++++++++++++++++----------------------------
 hw/xfree86/dri2/dri2.h    |  11 ++--
 hw/xfree86/dri2/dri2ext.c |   6 +-
 4 files changed, 66 insertions(+), 97 deletions(-)

diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 9d37b32..2bfacaa 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -105,7 +105,7 @@ __glXDRIdrawableDestroy(__GLXdrawable * drawable)
     __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
     const __DRIcoreExtension *core = private->screen->core;
 
-    FreeResource(private->dri2_id, FALSE);
+    DRI2DestroyDrawable(NULL, private->base.pDraw, private->dri2_id);
 
     (*core->destroyDrawable) (private->driDrawable);
 
@@ -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



More information about the xorg-devel mailing list