mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2026-05-09 04:58:06 +02:00
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>
This commit is contained in:
parent
0460a76b9a
commit
0c499f2ee4
3 changed files with 37 additions and 123 deletions
|
|
@ -105,11 +105,6 @@ __glXDRIdrawableDestroy(__GLXdrawable *drawable)
|
||||||
|
|
||||||
(*core->destroyDrawable)(private->driDrawable);
|
(*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);
|
__glXDrawableRelease(drawable);
|
||||||
|
|
||||||
xfree(private);
|
xfree(private);
|
||||||
|
|
|
||||||
|
|
@ -45,15 +45,14 @@
|
||||||
|
|
||||||
#include "xf86.h"
|
#include "xf86.h"
|
||||||
|
|
||||||
static int dri2ScreenPrivateKeyIndex;
|
static int dri2ScreenPrivateKeyIndex;
|
||||||
static DevPrivateKey dri2ScreenPrivateKey = &dri2ScreenPrivateKeyIndex;
|
static DevPrivateKey dri2ScreenPrivateKey = &dri2ScreenPrivateKeyIndex;
|
||||||
static int dri2WindowPrivateKeyIndex;
|
static RESTYPE dri2DrawableRes;
|
||||||
static DevPrivateKey dri2WindowPrivateKey = &dri2WindowPrivateKeyIndex;
|
|
||||||
static int dri2PixmapPrivateKeyIndex;
|
typedef struct _DRI2Screen *DRI2ScreenPtr;
|
||||||
static DevPrivateKey dri2PixmapPrivateKey = &dri2PixmapPrivateKeyIndex;
|
|
||||||
|
|
||||||
typedef struct _DRI2Drawable {
|
typedef struct _DRI2Drawable {
|
||||||
unsigned int refCount;
|
DRI2ScreenPtr dri2_screen;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
DRI2BufferPtr *buffers;
|
DRI2BufferPtr *buffers;
|
||||||
|
|
@ -67,9 +66,8 @@ typedef struct _DRI2Drawable {
|
||||||
int swap_limit; /* for N-buffering */
|
int swap_limit; /* for N-buffering */
|
||||||
} DRI2DrawableRec, *DRI2DrawablePtr;
|
} DRI2DrawableRec, *DRI2DrawablePtr;
|
||||||
|
|
||||||
typedef struct _DRI2Screen *DRI2ScreenPtr;
|
|
||||||
|
|
||||||
typedef struct _DRI2Screen {
|
typedef struct _DRI2Screen {
|
||||||
|
ScreenPtr screen;
|
||||||
unsigned int numDrivers;
|
unsigned int numDrivers;
|
||||||
const char **driverNames;
|
const char **driverNames;
|
||||||
const char *deviceName;
|
const char *deviceName;
|
||||||
|
|
@ -95,43 +93,33 @@ DRI2GetScreen(ScreenPtr pScreen)
|
||||||
static DRI2DrawablePtr
|
static DRI2DrawablePtr
|
||||||
DRI2GetDrawable(DrawablePtr pDraw)
|
DRI2GetDrawable(DrawablePtr pDraw)
|
||||||
{
|
{
|
||||||
WindowPtr pWin;
|
DRI2DrawablePtr pPriv;
|
||||||
PixmapPtr pPixmap;
|
int rc;
|
||||||
|
|
||||||
if (!pDraw)
|
rc = dixLookupResourceByType((pointer *) &pPriv, pDraw->id,
|
||||||
|
dri2DrawableRes, NULL, DixReadAccess);
|
||||||
|
if (rc != Success)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (pDraw->type == DRAWABLE_WINDOW)
|
return pPriv;
|
||||||
{
|
|
||||||
pWin = (WindowPtr) pDraw;
|
|
||||||
return dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pPixmap = (PixmapPtr) pDraw;
|
|
||||||
return dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
DRI2CreateDrawable(DrawablePtr pDraw)
|
DRI2CreateDrawable(DrawablePtr pDraw)
|
||||||
{
|
{
|
||||||
WindowPtr pWin;
|
|
||||||
PixmapPtr pPixmap;
|
|
||||||
DRI2DrawablePtr pPriv;
|
DRI2DrawablePtr pPriv;
|
||||||
|
int rc;
|
||||||
|
|
||||||
pPriv = DRI2GetDrawable(pDraw);
|
rc = dixLookupResourceByType((pointer *) &pPriv, pDraw->id,
|
||||||
if (pPriv != NULL)
|
dri2DrawableRes, NULL, DixReadAccess);
|
||||||
{
|
if (rc == Success || rc != BadValue)
|
||||||
pPriv->refCount++;
|
return rc;
|
||||||
return Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
pPriv = xalloc(sizeof *pPriv);
|
pPriv = xalloc(sizeof *pPriv);
|
||||||
if (pPriv == NULL)
|
if (pPriv == NULL)
|
||||||
return BadAlloc;
|
return BadAlloc;
|
||||||
|
|
||||||
pPriv->refCount = 1;
|
pPriv->dri2_screen = DRI2GetScreen(pDraw->pScreen);
|
||||||
pPriv->width = pDraw->width;
|
pPriv->width = pDraw->width;
|
||||||
pPriv->height = pDraw->height;
|
pPriv->height = pDraw->height;
|
||||||
pPriv->buffers = NULL;
|
pPriv->buffers = NULL;
|
||||||
|
|
@ -144,43 +132,30 @@ DRI2CreateDrawable(DrawablePtr pDraw)
|
||||||
pPriv->last_swap_target = -1;
|
pPriv->last_swap_target = -1;
|
||||||
pPriv->swap_limit = 1; /* default to double buffering */
|
pPriv->swap_limit = 1; /* default to double buffering */
|
||||||
|
|
||||||
if (pDraw->type == DRAWABLE_WINDOW)
|
if (!AddResource(pDraw->id, dri2DrawableRes, pPriv))
|
||||||
{
|
return BadAlloc;
|
||||||
pWin = (WindowPtr) pDraw;
|
|
||||||
dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, pPriv);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pPixmap = (PixmapPtr) pDraw;
|
|
||||||
dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, pPriv);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int DRI2DrawableGone(pointer p, XID id)
|
||||||
DRI2FreeDrawable(DrawablePtr pDraw)
|
|
||||||
{
|
{
|
||||||
DRI2DrawablePtr pPriv;
|
DRI2DrawablePtr pPriv = p;
|
||||||
WindowPtr pWin;
|
DRI2ScreenPtr ds = pPriv->dri2_screen;
|
||||||
PixmapPtr pPixmap;
|
DrawablePtr root;
|
||||||
|
int i;
|
||||||
|
|
||||||
pPriv = DRI2GetDrawable(pDraw);
|
root = &WindowTable[ds->screen->myNum]->drawable;
|
||||||
if (pPriv == NULL)
|
if (pPriv->buffers != NULL) {
|
||||||
return;
|
for (i = 0; i < pPriv->bufferCount; i++)
|
||||||
|
(*ds->DestroyBuffer)(root, pPriv->buffers[i]);
|
||||||
|
|
||||||
|
xfree(pPriv->buffers);
|
||||||
|
}
|
||||||
|
|
||||||
xfree(pPriv);
|
xfree(pPriv);
|
||||||
|
|
||||||
if (pDraw->type == DRAWABLE_WINDOW)
|
return Success;
|
||||||
{
|
|
||||||
pWin = (WindowPtr) pDraw;
|
|
||||||
dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pPixmap = (PixmapPtr) pDraw;
|
|
||||||
dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
@ -534,13 +509,6 @@ DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int frame,
|
||||||
return;
|
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;
|
ust = ((CARD64)tv_sec * 1000000) + tv_usec;
|
||||||
if (swap_complete)
|
if (swap_complete)
|
||||||
swap_complete(client, swap_data, type, ust, frame, pPriv->swap_count);
|
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;
|
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
|
Bool
|
||||||
DRI2Connect(ScreenPtr pScreen, unsigned int driverType, int *fd,
|
DRI2Connect(ScreenPtr pScreen, unsigned int driverType, int *fd,
|
||||||
const char **driverName, const char **deviceName)
|
const char **driverName, const char **deviceName)
|
||||||
|
|
@ -834,6 +772,7 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
|
||||||
if (!ds)
|
if (!ds)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
ds->screen = pScreen;
|
||||||
ds->fd = info->fd;
|
ds->fd = info->fd;
|
||||||
ds->deviceName = info->deviceName;
|
ds->deviceName = info->deviceName;
|
||||||
|
|
||||||
|
|
@ -897,6 +836,8 @@ DRI2Setup(pointer module, pointer opts, int *errmaj, int *errmin)
|
||||||
{
|
{
|
||||||
static Bool setupDone = FALSE;
|
static Bool setupDone = FALSE;
|
||||||
|
|
||||||
|
dri2DrawableRes = CreateNewResourceType(DRI2DrawableGone, "DRI2Drawable");
|
||||||
|
|
||||||
if (!setupDone)
|
if (!setupDone)
|
||||||
{
|
{
|
||||||
setupDone = TRUE;
|
setupDone = TRUE;
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,6 @@
|
||||||
#include "xf86Module.h"
|
#include "xf86Module.h"
|
||||||
|
|
||||||
static ExtensionEntry *dri2Extension;
|
static ExtensionEntry *dri2Extension;
|
||||||
static RESTYPE dri2DrawableRes;
|
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
validDrawable(ClientPtr client, XID drawable, Mask access_mode,
|
validDrawable(ClientPtr client, XID drawable, Mask access_mode,
|
||||||
|
|
@ -172,11 +171,6 @@ ProcDRI2CreateDrawable(ClientPtr client)
|
||||||
if (status != Success)
|
if (status != Success)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
if (!AddResource(stuff->drawable, dri2DrawableRes, pDrawable)) {
|
|
||||||
DRI2DestroyDrawable(pDrawable);
|
|
||||||
return BadAlloc;
|
|
||||||
}
|
|
||||||
|
|
||||||
return client->noClientException;
|
return client->noClientException;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -192,8 +186,6 @@ ProcDRI2DestroyDrawable(ClientPtr client)
|
||||||
&pDrawable, &status))
|
&pDrawable, &status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
FreeResourceByType(stuff->drawable, dri2DrawableRes, FALSE);
|
|
||||||
|
|
||||||
return client->noClientException;
|
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;
|
int DRI2EventBase;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
DRI2ExtensionInit(void)
|
DRI2ExtensionInit(void)
|
||||||
{
|
{
|
||||||
dri2DrawableRes = CreateNewResourceType(DRI2DrawableGone, "DRI2Drawable");
|
|
||||||
|
|
||||||
if (!dri2DrawableRes)
|
|
||||||
return;
|
|
||||||
|
|
||||||
dri2Extension = AddExtension(DRI2_NAME,
|
dri2Extension = AddExtension(DRI2_NAME,
|
||||||
DRI2NumberEvents,
|
DRI2NumberEvents,
|
||||||
DRI2NumberErrors,
|
DRI2NumberErrors,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue