summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2010-04-16 05:55:34 -0400
committerAdam Jackson <ajax@redhat.com>2010-04-20 14:18:19 -0400
commit0c499f2ee4ae2b7dc424009abb336fc81a8a2853 (patch)
treeabb716d7ae40eb6d6f1fe1c51c1ab37512dfe2c4
parent0460a76b9ae25fe26f683f0cbff1e4157287cf56 (diff)
DRI2: Track DRI2 drawables as resources, not privates
The main motivation here is to have the resource system clean up the DRI2 drawable automatically so glx doesn't have to. Right now, the glx drawable resource must be destroyed before the X drawable, so that calling DRI2DestroyDrawable doesn't crash. By making the DRI2 drawable a resource, GLX doesn't have to worry about that and the resource destruction order becomes irrelevant. https://bugs.freedesktop.org/show_bug.cgi?id=26394 [Ported to 1.8 branch by ajax@redhat.com] Signed-off-by: Kristian Høgsberg <krh@bitplanet.net> Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--glx/glxdri2.c5
-rw-r--r--hw/xfree86/dri2/dri2.c133
-rw-r--r--hw/xfree86/dri2/dri2ext.c22
3 files changed, 37 insertions, 123 deletions
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index edd29b0e1..bde519a2f 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -105,11 +105,6 @@ __glXDRIdrawableDestroy(__GLXdrawable *drawable)
(*core->destroyDrawable)(private->driDrawable);
- /* If the X window was destroyed, the dri DestroyWindow hook will
- * aready have taken care of this, so only call if pDraw isn't NULL. */
- if (drawable->pDraw != NULL)
- DRI2DestroyDrawable(drawable->pDraw);
-
__glXDrawableRelease(drawable);
xfree(private);
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 48618e1a5..63bef2814 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -45,15 +45,14 @@
#include "xf86.h"
-static int dri2ScreenPrivateKeyIndex;
+static int dri2ScreenPrivateKeyIndex;
static DevPrivateKey dri2ScreenPrivateKey = &dri2ScreenPrivateKeyIndex;
-static int dri2WindowPrivateKeyIndex;
-static DevPrivateKey dri2WindowPrivateKey = &dri2WindowPrivateKeyIndex;
-static int dri2PixmapPrivateKeyIndex;
-static DevPrivateKey dri2PixmapPrivateKey = &dri2PixmapPrivateKeyIndex;
+static RESTYPE dri2DrawableRes;
+
+typedef struct _DRI2Screen *DRI2ScreenPtr;
typedef struct _DRI2Drawable {
- unsigned int refCount;
+ DRI2ScreenPtr dri2_screen;
int width;
int height;
DRI2BufferPtr *buffers;
@@ -67,9 +66,8 @@ typedef struct _DRI2Drawable {
int swap_limit; /* for N-buffering */
} DRI2DrawableRec, *DRI2DrawablePtr;
-typedef struct _DRI2Screen *DRI2ScreenPtr;
-
typedef struct _DRI2Screen {
+ ScreenPtr screen;
unsigned int numDrivers;
const char **driverNames;
const char *deviceName;
@@ -95,43 +93,33 @@ DRI2GetScreen(ScreenPtr pScreen)
static DRI2DrawablePtr
DRI2GetDrawable(DrawablePtr pDraw)
{
- WindowPtr pWin;
- PixmapPtr pPixmap;
-
- if (!pDraw)
+ DRI2DrawablePtr pPriv;
+ int rc;
+
+ rc = dixLookupResourceByType((pointer *) &pPriv, pDraw->id,
+ dri2DrawableRes, NULL, DixReadAccess);
+ if (rc != Success)
return NULL;
- if (pDraw->type == DRAWABLE_WINDOW)
- {
- pWin = (WindowPtr) pDraw;
- return dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey);
- }
- else
- {
- pPixmap = (PixmapPtr) pDraw;
- return dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey);
- }
+ return pPriv;
}
int
DRI2CreateDrawable(DrawablePtr pDraw)
{
- WindowPtr pWin;
- PixmapPtr pPixmap;
DRI2DrawablePtr pPriv;
+ int rc;
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv != NULL)
- {
- pPriv->refCount++;
- return Success;
- }
+ rc = dixLookupResourceByType((pointer *) &pPriv, pDraw->id,
+ dri2DrawableRes, NULL, DixReadAccess);
+ if (rc == Success || rc != BadValue)
+ return rc;
pPriv = xalloc(sizeof *pPriv);
if (pPriv == NULL)
return BadAlloc;
- pPriv->refCount = 1;
+ pPriv->dri2_screen = DRI2GetScreen(pDraw->pScreen);
pPriv->width = pDraw->width;
pPriv->height = pDraw->height;
pPriv->buffers = NULL;
@@ -144,43 +132,30 @@ DRI2CreateDrawable(DrawablePtr pDraw)
pPriv->last_swap_target = -1;
pPriv->swap_limit = 1; /* default to double buffering */
- if (pDraw->type == DRAWABLE_WINDOW)
- {
- pWin = (WindowPtr) pDraw;
- dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, pPriv);
- }
- else
- {
- pPixmap = (PixmapPtr) pDraw;
- dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, pPriv);
- }
+ if (!AddResource(pDraw->id, dri2DrawableRes, pPriv))
+ return BadAlloc;
return Success;
}
-static void
-DRI2FreeDrawable(DrawablePtr pDraw)
+static int DRI2DrawableGone(pointer p, XID id)
{
- DRI2DrawablePtr pPriv;
- WindowPtr pWin;
- PixmapPtr pPixmap;
+ DRI2DrawablePtr pPriv = p;
+ DRI2ScreenPtr ds = pPriv->dri2_screen;
+ DrawablePtr root;
+ int i;
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL)
- return;
+ root = &WindowTable[ds->screen->myNum]->drawable;
+ if (pPriv->buffers != NULL) {
+ for (i = 0; i < pPriv->bufferCount; i++)
+ (*ds->DestroyBuffer)(root, pPriv->buffers[i]);
+
+ xfree(pPriv->buffers);
+ }
xfree(pPriv);
- if (pDraw->type == DRAWABLE_WINDOW)
- {
- pWin = (WindowPtr) pDraw;
- dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL);
- }
- else
- {
- pPixmap = (PixmapPtr) pDraw;
- dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, NULL);
- }
+ return Success;
}
static int
@@ -534,13 +509,6 @@ DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int frame,
return;
}
- if (pPriv->refCount == 0) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[DRI2] %s: bad drawable refcount\n", __func__);
- DRI2FreeDrawable(pDraw);
- return;
- }
-
ust = ((CARD64)tv_sec * 1000000) + tv_usec;
if (swap_complete)
swap_complete(client, swap_data, type, ust, frame, pPriv->swap_count);
@@ -753,36 +721,6 @@ DRI2WaitSBC(ClientPtr client, DrawablePtr pDraw, CARD64 target_sbc,
return Success;
}
-void
-DRI2DestroyDrawable(DrawablePtr pDraw)
-{
- DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
- DRI2DrawablePtr pPriv;
-
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL)
- return;
-
- pPriv->refCount--;
- if (pPriv->refCount > 0)
- return;
-
- if (pPriv->buffers != NULL) {
- int i;
-
- for (i = 0; i < pPriv->bufferCount; i++)
- (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
-
- xfree(pPriv->buffers);
- }
-
- /* If the window is destroyed while we have a swap pending, don't
- * actually free the priv yet. We'll need it in the DRI2SwapComplete()
- * callback and we'll free it there once we're done. */
- if (!pPriv->swapsPending)
- DRI2FreeDrawable(pDraw);
-}
-
Bool
DRI2Connect(ScreenPtr pScreen, unsigned int driverType, int *fd,
const char **driverName, const char **deviceName)
@@ -834,6 +772,7 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
if (!ds)
return FALSE;
+ ds->screen = pScreen;
ds->fd = info->fd;
ds->deviceName = info->deviceName;
@@ -897,6 +836,8 @@ DRI2Setup(pointer module, pointer opts, int *errmaj, int *errmin)
{
static Bool setupDone = FALSE;
+ dri2DrawableRes = CreateNewResourceType(DRI2DrawableGone, "DRI2Drawable");
+
if (!setupDone)
{
setupDone = TRUE;
diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
index bd92fd304..1ac4a5fc5 100644
--- a/hw/xfree86/dri2/dri2ext.c
+++ b/hw/xfree86/dri2/dri2ext.c
@@ -51,7 +51,6 @@
#include "xf86Module.h"
static ExtensionEntry *dri2Extension;
-static RESTYPE dri2DrawableRes;
static Bool
validDrawable(ClientPtr client, XID drawable, Mask access_mode,
@@ -172,11 +171,6 @@ ProcDRI2CreateDrawable(ClientPtr client)
if (status != Success)
return status;
- if (!AddResource(stuff->drawable, dri2DrawableRes, pDrawable)) {
- DRI2DestroyDrawable(pDrawable);
- return BadAlloc;
- }
-
return client->noClientException;
}
@@ -192,8 +186,6 @@ ProcDRI2DestroyDrawable(ClientPtr client)
&pDrawable, &status))
return status;
- FreeResourceByType(stuff->drawable, dri2DrawableRes, FALSE);
-
return client->noClientException;
}
@@ -620,25 +612,11 @@ SProcDRI2Dispatch (ClientPtr client)
}
}
-static int DRI2DrawableGone(pointer p, XID id)
-{
- DrawablePtr pDrawable = p;
-
- DRI2DestroyDrawable(pDrawable);
-
- return Success;
-}
-
int DRI2EventBase;
static void
DRI2ExtensionInit(void)
{
- dri2DrawableRes = CreateNewResourceType(DRI2DrawableGone, "DRI2Drawable");
-
- if (!dri2DrawableRes)
- return;
-
dri2Extension = AddExtension(DRI2_NAME,
DRI2NumberEvents,
DRI2NumberErrors,