summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2010-04-27 17:53:22 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2010-04-27 19:01:14 +1000
commitc394b17266301d363a9e234f58f8015f74e01307 (patch)
tree4e210778312c77c19b30fcdcfe4f5065cf3d3d2a
parent65e84507b48546443fd0f67bc3263903d116bf62 (diff)
Revert "DRI2: Track DRI2 drawables as resources, not privates"
This change breaks GLX compositing managers. See Bug 27767 <https://bugs.freedesktop.org/show_bug.cgi?id=27767> This reverts commit 0c499f2ee4ae2b7dc424009abb336fc81a8a2853. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-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, 123 insertions, 37 deletions
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index bde519a2f..edd29b0e1 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -105,6 +105,11 @@ __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 63bef2814..48618e1a5 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -45,14 +45,15 @@
#include "xf86.h"
-static int dri2ScreenPrivateKeyIndex;
+static int dri2ScreenPrivateKeyIndex;
static DevPrivateKey dri2ScreenPrivateKey = &dri2ScreenPrivateKeyIndex;
-static RESTYPE dri2DrawableRes;
-
-typedef struct _DRI2Screen *DRI2ScreenPtr;
+static int dri2WindowPrivateKeyIndex;
+static DevPrivateKey dri2WindowPrivateKey = &dri2WindowPrivateKeyIndex;
+static int dri2PixmapPrivateKeyIndex;
+static DevPrivateKey dri2PixmapPrivateKey = &dri2PixmapPrivateKeyIndex;
typedef struct _DRI2Drawable {
- DRI2ScreenPtr dri2_screen;
+ unsigned int refCount;
int width;
int height;
DRI2BufferPtr *buffers;
@@ -66,8 +67,9 @@ 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;
@@ -93,33 +95,43 @@ DRI2GetScreen(ScreenPtr pScreen)
static DRI2DrawablePtr
DRI2GetDrawable(DrawablePtr pDraw)
{
- DRI2DrawablePtr pPriv;
- int rc;
-
- rc = dixLookupResourceByType((pointer *) &pPriv, pDraw->id,
- dri2DrawableRes, NULL, DixReadAccess);
- if (rc != Success)
+ WindowPtr pWin;
+ PixmapPtr pPixmap;
+
+ if (!pDraw)
return NULL;
- return pPriv;
+ if (pDraw->type == DRAWABLE_WINDOW)
+ {
+ pWin = (WindowPtr) pDraw;
+ return dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey);
+ }
+ else
+ {
+ pPixmap = (PixmapPtr) pDraw;
+ return dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey);
+ }
}
int
DRI2CreateDrawable(DrawablePtr pDraw)
{
+ WindowPtr pWin;
+ PixmapPtr pPixmap;
DRI2DrawablePtr pPriv;
- int rc;
- rc = dixLookupResourceByType((pointer *) &pPriv, pDraw->id,
- dri2DrawableRes, NULL, DixReadAccess);
- if (rc == Success || rc != BadValue)
- return rc;
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv != NULL)
+ {
+ pPriv->refCount++;
+ return Success;
+ }
pPriv = xalloc(sizeof *pPriv);
if (pPriv == NULL)
return BadAlloc;
- pPriv->dri2_screen = DRI2GetScreen(pDraw->pScreen);
+ pPriv->refCount = 1;
pPriv->width = pDraw->width;
pPriv->height = pDraw->height;
pPriv->buffers = NULL;
@@ -132,30 +144,43 @@ DRI2CreateDrawable(DrawablePtr pDraw)
pPriv->last_swap_target = -1;
pPriv->swap_limit = 1; /* default to double buffering */
- if (!AddResource(pDraw->id, dri2DrawableRes, pPriv))
- return BadAlloc;
+ if (pDraw->type == DRAWABLE_WINDOW)
+ {
+ pWin = (WindowPtr) pDraw;
+ dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, pPriv);
+ }
+ else
+ {
+ pPixmap = (PixmapPtr) pDraw;
+ dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, pPriv);
+ }
return Success;
}
-static int DRI2DrawableGone(pointer p, XID id)
+static void
+DRI2FreeDrawable(DrawablePtr pDraw)
{
- DRI2DrawablePtr pPriv = p;
- DRI2ScreenPtr ds = pPriv->dri2_screen;
- DrawablePtr root;
- int i;
-
- root = &WindowTable[ds->screen->myNum]->drawable;
- if (pPriv->buffers != NULL) {
- for (i = 0; i < pPriv->bufferCount; i++)
- (*ds->DestroyBuffer)(root, pPriv->buffers[i]);
+ DRI2DrawablePtr pPriv;
+ WindowPtr pWin;
+ PixmapPtr pPixmap;
- xfree(pPriv->buffers);
- }
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL)
+ return;
xfree(pPriv);
- return Success;
+ if (pDraw->type == DRAWABLE_WINDOW)
+ {
+ pWin = (WindowPtr) pDraw;
+ dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL);
+ }
+ else
+ {
+ pPixmap = (PixmapPtr) pDraw;
+ dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, NULL);
+ }
}
static int
@@ -509,6 +534,13 @@ 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);
@@ -721,6 +753,36 @@ 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)
@@ -772,7 +834,6 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
if (!ds)
return FALSE;
- ds->screen = pScreen;
ds->fd = info->fd;
ds->deviceName = info->deviceName;
@@ -836,8 +897,6 @@ 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 1ac4a5fc5..bd92fd304 100644
--- a/hw/xfree86/dri2/dri2ext.c
+++ b/hw/xfree86/dri2/dri2ext.c
@@ -51,6 +51,7 @@
#include "xf86Module.h"
static ExtensionEntry *dri2Extension;
+static RESTYPE dri2DrawableRes;
static Bool
validDrawable(ClientPtr client, XID drawable, Mask access_mode,
@@ -171,6 +172,11 @@ ProcDRI2CreateDrawable(ClientPtr client)
if (status != Success)
return status;
+ if (!AddResource(stuff->drawable, dri2DrawableRes, pDrawable)) {
+ DRI2DestroyDrawable(pDrawable);
+ return BadAlloc;
+ }
+
return client->noClientException;
}
@@ -186,6 +192,8 @@ ProcDRI2DestroyDrawable(ClientPtr client)
&pDrawable, &status))
return status;
+ FreeResourceByType(stuff->drawable, dri2DrawableRes, FALSE);
+
return client->noClientException;
}
@@ -612,11 +620,25 @@ 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,