[PATCH 2/3] dri2: Only create one unnamed reference per Drawable per Client

Chris Wilson chris at chris-wilson.co.uk
Sat Feb 21 13:31:09 PST 2015


This workarounds issues in mesa and Mali that likes to create a new
DRI2Drawble per context and per frame, respectively. The idea is that we
only create one unnamed reference per Client on each Drawable that is
never destroyed - and we make the assumption that the only caller is
the DRI2 dispatcher and thus we don't need to check that the invalidate
handler is the same.

Cc: Daniel Drake <drake at endlessm.com>
Link: https://freedesktop.org/patch/19695/
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 hw/xfree86/dri2/dri2.c    | 22 ++++++++++++++++++++--
 hw/xfree86/dri2/dri2ext.c |  2 +-
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index af286e6..bfa551e 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -279,6 +279,7 @@ DRI2SwapLimit(DrawablePtr pDraw, int swap_limit)
 
 typedef struct DRI2DrawableRefRec {
     XID pid;
+    unsigned int unnamed:1;
     DRI2InvalidateProcPtr invalidate;
     void *priv;
     struct xorg_list link;
@@ -299,16 +300,33 @@ DRI2CreateDrawable(ClientPtr client, DrawablePtr pDraw, XID pid,
 
     pPriv->prime_id = dri2ClientPrivate(client)->prime_id;
 
+    if (pid == 0) {
+        xorg_list_for_each_entry(ref, &pPriv->reference_list, link)
+            if (ref->unnamed && CLIENT_ID(ref->pid) == client->index) {
+                assert(ref->invalidate == invalidate);
+                assert(ref->priv == priv);
+                return Success;
+            }
+    }
+
     ref = malloc(sizeof *ref);
     if (ref == NULL)
         return BadAlloc;
 
-    if (!AddResource(pid, dri2ReferenceRes, ref)) {
+    if (pid == 0) {
+        ref->unnamed = 1;
+        ref->pid = FakeClientID(client->index);
+    }
+    else {
+        ref->unnamed = 0;
+        ref->pid = pid;
+    }
+
+    if (!AddResource(ref->pid, dri2ReferenceRes, ref)) {
         free(ref);
         return BadAlloc;
     }
 
-    ref->pid = pid;
     ref->invalidate = invalidate;
     ref->priv = priv;
     xorg_list_add(&ref->link, &pPriv->reference_list);
diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
index 5dae806..8e70bc5 100644
--- a/hw/xfree86/dri2/dri2ext.c
+++ b/hw/xfree86/dri2/dri2ext.c
@@ -185,7 +185,7 @@ ProcDRI2CreateDrawable(ClientPtr client)
                        &pDrawable, &status))
         return status;
 
-    status = DRI2CreateDrawable(client, pDrawable, FakeClientID(client->index),
+    status = DRI2CreateDrawable(client, pDrawable, 0,
                                 DRI2InvalidateBuffersEvent, client);
     if (status != Success)
         return status;
-- 
2.1.4



More information about the xorg-devel mailing list