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 <dr...@endlessm.com> Link: https://freedesktop.org/patch/19695/ Signed-off-by: Chris Wilson <ch...@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 _______________________________________________ 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