summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPauli Nieminen <ext-pauli.nieminen@nokia.com>2011-02-01 21:41:30 +0200
committerPauli Nieminen <ext-pauli.nieminen@nokia.com>2011-02-04 17:34:06 +0200
commit398ba91b8ad067eabfc645ef54711789bf25b1f3 (patch)
treeb32f08f84818940519d7d59cdc3b51cd8bca9d6f
parent21bff5348601ba10d9a69e6879f0b7dbc902b89f (diff)
dri2: Keep DRI2Drawable resource allocated until creator frees it
EGLImage requires that image siblings stay valid until all of them has been freed. Base EGLImage is only required for creating new siblings. http://www.khronos.org/registry/egl/extensions/KHR/EGL_KHR_image_base.txt To keep DRI2Drawable until all siblings has been destroyed we need to extent life time of DRI2Drawable beyond the Drawable. We can keep the fake dri2 resource allocated. DRI2 can then searched for fake resource if client tries to use DRI2Drawable after Drawable was destroyed. Signed-off-by: Pauli Nieminen <ext-pauli.nieminen@nokia.com>
-rw-r--r--hw/xfree86/dri2/dri2.c43
-rw-r--r--hw/xfree86/dri2/dri2.h4
-rw-r--r--hw/xfree86/dri2/dri2ext.c6
3 files changed, 35 insertions, 18 deletions
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 9f262aeef..30e36e8ca 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -238,6 +238,26 @@ DRI2LookupClientDrawableRef(DRI2DrawablePtr pPriv, ClientPtr client, XID id)
return NULL;
}
+static Bool
+DRI2MatchDrawableRef(pointer data, XID fake_id, pointer cdata)
+{
+ DRI2DrawablePtr pPriv = data;
+ XID id = (XID)cdata;
+ DRI2DrawableRefPtr ref = DRI2LookupDrawableRef(pPriv, id);
+ return ref != NULL;
+}
+
+int
+DRI2LookupDrawableComplex(ClientPtr client, XID id, DRI2DrawablePtr *pPriv)
+{
+ DRI2DrawablePtr tmp = LookupClientResourceComplex(client, dri2DrawableRes,
+ DRI2MatchDrawableRef, (pointer)id);
+ if (!tmp)
+ return BadDrawable;
+ *pPriv = tmp;
+ return Success;
+}
+
static int
DRI2AddDrawableRef(DRI2DrawablePtr pPriv, XID id, XID dri2_id,
DRI2InvalidateProcPtr invalidate, void *priv)
@@ -307,9 +327,7 @@ static int DRI2DrawableGone(pointer p, XID id)
DRI2DrawablePtr pPriv = p;
DRI2ScreenPtr ds = pPriv->dri2_screen;
DRI2DrawableRefPtr ref, next;
- WindowPtr pWin;
- PixmapPtr pPixmap;
- DrawablePtr pDraw;
+ DrawablePtr pDraw = pPriv->drawable;
int i;
list_for_each_entry_safe(ref, next, &pPriv->reference_list, link) {
@@ -324,11 +342,10 @@ static int DRI2DrawableGone(pointer p, XID id)
break;
}
- if (ref->id == id) {
- pPriv->refcnt--;
- list_del(&ref->link);
- FreeResourceByType(ref->dri2_id, dri2DrawableRes, TRUE);
- free(ref);
+ if (ref->id == id && pDraw && pDraw->type == DRAWABLE_WINDOW) {
+ WindowPtr pWin = (WindowPtr) pDraw;
+ dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL);
+ pPriv->drawable = NULL;
}
}
@@ -336,13 +353,11 @@ static int DRI2DrawableGone(pointer p, XID id)
if (pPriv->refcnt > 0)
return Success;
- pDraw = pPriv->drawable;
-
- if (pDraw->type == DRAWABLE_WINDOW) {
- pWin = (WindowPtr) pDraw;
+ if (pDraw && pDraw->type == DRAWABLE_WINDOW) {
+ WindowPtr pWin = (WindowPtr) pDraw;
dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL);
- } else {
- pPixmap = (PixmapPtr) pDraw;
+ } else if (pDraw) {
+ PixmapPtr pPixmap = (PixmapPtr) pDraw;
dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, NULL);
pDraw->pScreen->DestroyPixmap(pPixmap);
}
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
index 2c11e6bd6..071fe4c2b 100644
--- a/hw/xfree86/dri2/dri2.h
+++ b/hw/xfree86/dri2/dri2.h
@@ -321,4 +321,8 @@ extern _X_EXPORT ScreenPtr DRI2DrawableGetScreen(DRI2DrawablePtr pPriv);
* \return Valid DRI2DrawablePtr if DRI2Drawable exists. Otherwise NULL.
*/
extern _X_EXPORT DRI2DrawablePtr DRI2GetDrawable(DrawablePtr pDraw);
+
+extern _X_EXPORT int DRI2LookupDrawableComplex(ClientPtr client,
+ XID id,
+ DRI2DrawablePtr *pPriv);
#endif
diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
index bac7b79ba..beadc832b 100644
--- a/hw/xfree86/dri2/dri2ext.c
+++ b/hw/xfree86/dri2/dri2ext.c
@@ -66,10 +66,8 @@ validDRI2Drawable(ClientPtr client, XID id, Mask access,
rc = dixLookupResourceByType((pointer*)&pTmp, id, dri2DrawableRes, client, access);
- if (rc == BadValue) {
- *status = BadDrawable;
- return FALSE;
- }
+ if (rc == BadValue)
+ rc = DRI2LookupDrawableComplex(client, id, &pTmp);
*status = rc;
if (rc != Success)
return FALSE;