mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2026-05-03 14:48:03 +02:00
Merge branch 'dri2-backports' into server-1.8-branch
This commit is contained in:
commit
600bdf0350
10 changed files with 184 additions and 139 deletions
|
|
@ -589,6 +589,7 @@ FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
|
|||
res->value, TypeNameString(res->type));
|
||||
#endif
|
||||
*prev = res->next;
|
||||
clientTable[cid].elements--;
|
||||
|
||||
CallResourceStateCallback(ResourceStateFreeing, res);
|
||||
|
||||
|
|
@ -734,12 +735,14 @@ FreeClientNeverRetainResources(ClientPtr client)
|
|||
ResourcePtr *resources;
|
||||
ResourcePtr this;
|
||||
ResourcePtr *prev;
|
||||
int j;
|
||||
int j, elements;
|
||||
int *eltptr;
|
||||
|
||||
if (!client)
|
||||
return;
|
||||
|
||||
resources = clientTable[client->index].resources;
|
||||
eltptr = &clientTable[client->index].elements;
|
||||
for (j=0; j < clientTable[client->index].buckets; j++)
|
||||
{
|
||||
prev = &resources[j];
|
||||
|
|
@ -753,11 +756,15 @@ FreeClientNeverRetainResources(ClientPtr client)
|
|||
this->value, TypeNameString(this->type));
|
||||
#endif
|
||||
*prev = this->next;
|
||||
clientTable[client->index].elements--;
|
||||
|
||||
CallResourceStateCallback(ResourceStateFreeing, this);
|
||||
|
||||
elements = *eltptr;
|
||||
(*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
|
||||
xfree(this);
|
||||
if (*eltptr != elements)
|
||||
prev = &resources[j]; /* prev may no longer be valid */
|
||||
}
|
||||
else
|
||||
prev = &this->next;
|
||||
|
|
@ -804,6 +811,7 @@ FreeClientResources(ClientPtr client)
|
|||
this->value, TypeNameString(this->type));
|
||||
#endif
|
||||
*head = this->next;
|
||||
clientTable[client->index].elements--;
|
||||
|
||||
CallResourceStateCallback(ResourceStateFreeing, this);
|
||||
|
||||
|
|
|
|||
|
|
@ -512,8 +512,9 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client,
|
|||
if (!validGlxFBConfigForWindow(client, glxc->config, pDraw, error))
|
||||
return NULL;
|
||||
|
||||
pGlxDraw = glxc->pGlxScreen->createDrawable(glxc->pGlxScreen,
|
||||
pDraw, GLX_DRAWABLE_WINDOW,
|
||||
pGlxDraw = glxc->pGlxScreen->createDrawable(client, glxc->pGlxScreen,
|
||||
pDraw, drawId,
|
||||
GLX_DRAWABLE_WINDOW,
|
||||
drawId, glxc->config);
|
||||
|
||||
/* since we are creating the drawablePrivate, drawId should be new */
|
||||
|
|
@ -1104,15 +1105,17 @@ __glXDrawableRelease(__GLXdrawable *drawable)
|
|||
}
|
||||
|
||||
static int
|
||||
DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config,
|
||||
DrawablePtr pDraw, XID glxDrawableId, int type)
|
||||
DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen,
|
||||
__GLXconfig *config, DrawablePtr pDraw, XID drawableId,
|
||||
XID glxDrawableId, int type)
|
||||
{
|
||||
__GLXdrawable *pGlxDraw;
|
||||
|
||||
if (pGlxScreen->pScreen != pDraw->pScreen)
|
||||
return BadMatch;
|
||||
|
||||
pGlxDraw = pGlxScreen->createDrawable(pGlxScreen, pDraw, type,
|
||||
pGlxDraw = pGlxScreen->createDrawable(client, pGlxScreen, pDraw,
|
||||
drawableId, type,
|
||||
glxDrawableId, config);
|
||||
if (pGlxDraw == NULL)
|
||||
return BadAlloc;
|
||||
|
|
@ -1125,7 +1128,7 @@ DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *conf
|
|||
/* Add the glx drawable under the XID of the underlying X drawable
|
||||
* too. That way we'll get a callback in DrawableGone and can
|
||||
* clean up properly when the drawable is destroyed. */
|
||||
if (pDraw->id != glxDrawableId &&
|
||||
if (drawableId != glxDrawableId &&
|
||||
!AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) {
|
||||
pGlxDraw->destroy (pGlxDraw);
|
||||
return BadAlloc;
|
||||
|
|
@ -1153,7 +1156,7 @@ DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config
|
|||
return BadPixmap;
|
||||
}
|
||||
|
||||
err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw,
|
||||
err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, drawableId,
|
||||
glxDrawableId, GLX_DRAWABLE_PIXMAP);
|
||||
|
||||
return err;
|
||||
|
|
@ -1316,7 +1319,8 @@ DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
|
|||
return BadAlloc;
|
||||
|
||||
return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable,
|
||||
glxDrawableId, GLX_DRAWABLE_PBUFFER);
|
||||
glxDrawableId, glxDrawableId,
|
||||
GLX_DRAWABLE_PBUFFER);
|
||||
}
|
||||
|
||||
int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc)
|
||||
|
|
@ -1439,7 +1443,8 @@ int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc)
|
|||
return err;
|
||||
|
||||
return DoCreateGLXDrawable(client, pGlxScreen, config,
|
||||
pDraw, req->glxwindow, GLX_DRAWABLE_WINDOW);
|
||||
pDraw, req->window,
|
||||
req->glxwindow, GLX_DRAWABLE_WINDOW);
|
||||
}
|
||||
|
||||
int __glXDisp_DestroyWindow(__GLXclientState *cl, GLbyte *pc)
|
||||
|
|
|
|||
|
|
@ -682,10 +682,12 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen,
|
|||
}
|
||||
|
||||
static __GLXdrawable *
|
||||
__glXDRIscreenCreateDrawable(__GLXscreen *screen,
|
||||
__glXDRIscreenCreateDrawable(ClientPtr client,
|
||||
__GLXscreen *screen,
|
||||
DrawablePtr pDraw,
|
||||
int type,
|
||||
XID drawId,
|
||||
int type,
|
||||
XID glxDrawId,
|
||||
__GLXconfig *glxConfig)
|
||||
{
|
||||
__GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
|
||||
|
|
@ -699,7 +701,7 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
|
|||
return NULL;
|
||||
|
||||
if (!__glXDrawableInit(&private->base, screen,
|
||||
pDraw, type, drawId, glxConfig)) {
|
||||
pDraw, type, glxDrawId, glxConfig)) {
|
||||
xfree(private);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -435,10 +430,12 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen,
|
|||
}
|
||||
|
||||
static __GLXdrawable *
|
||||
__glXDRIscreenCreateDrawable(__GLXscreen *screen,
|
||||
__glXDRIscreenCreateDrawable(ClientPtr client,
|
||||
__GLXscreen *screen,
|
||||
DrawablePtr pDraw,
|
||||
int type,
|
||||
XID drawId,
|
||||
int type,
|
||||
XID glxDrawId,
|
||||
__GLXconfig *glxConfig)
|
||||
{
|
||||
__GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
|
||||
|
|
@ -451,7 +448,7 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
|
|||
|
||||
private->screen = driScreen;
|
||||
if (!__glXDrawableInit(&private->base, screen,
|
||||
pDraw, type, drawId, glxConfig)) {
|
||||
pDraw, type, glxDrawId, glxConfig)) {
|
||||
xfree(private);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -462,7 +459,7 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
|
|||
private->base.waitGL = __glXDRIdrawableWaitGL;
|
||||
private->base.waitX = __glXDRIdrawableWaitX;
|
||||
|
||||
if (DRI2CreateDrawable(pDraw)) {
|
||||
if (DRI2CreateDrawable(client, pDraw, drawId)) {
|
||||
xfree(private);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -658,7 +655,7 @@ initializeExtensions(__GLXDRIscreen *screen)
|
|||
|
||||
#ifdef __DRI2_FLUSH
|
||||
if (strcmp(extensions[i]->name, __DRI2_FLUSH) == 0 &&
|
||||
extensions[i]->version >= __DRI2_FLUSH_VERSION) {
|
||||
extensions[i]->version >= 3) {
|
||||
screen->flush = (__DRI2flushExtension *) extensions[i];
|
||||
}
|
||||
#endif
|
||||
|
|
@ -718,11 +715,11 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
|
|||
|
||||
for (i = 0; extensions[i]; i++) {
|
||||
if (strcmp(extensions[i]->name, __DRI_CORE) == 0 &&
|
||||
extensions[i]->version >= __DRI_CORE_VERSION) {
|
||||
extensions[i]->version >= 1) {
|
||||
screen->core = (const __DRIcoreExtension *) extensions[i];
|
||||
}
|
||||
if (strcmp(extensions[i]->name, __DRI_DRI2) == 0 &&
|
||||
extensions[i]->version >= __DRI_DRI2_VERSION) {
|
||||
extensions[i]->version >= 1) {
|
||||
screen->dri2 = (const __DRIdri2Extension *) extensions[i];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -301,10 +301,12 @@ glxChangeGC(GCPtr gc, BITS32 mask, CARD32 val)
|
|||
}
|
||||
|
||||
static __GLXdrawable *
|
||||
__glXDRIscreenCreateDrawable(__GLXscreen *screen,
|
||||
__glXDRIscreenCreateDrawable(ClientPtr client,
|
||||
__GLXscreen *screen,
|
||||
DrawablePtr pDraw,
|
||||
int type,
|
||||
XID drawId,
|
||||
int type,
|
||||
XID glxDrawId,
|
||||
__GLXconfig *glxConfig)
|
||||
{
|
||||
__GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
|
||||
|
|
@ -319,7 +321,7 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
|
|||
|
||||
private->screen = driScreen;
|
||||
if (!__glXDrawableInit(&private->base, screen,
|
||||
pDraw, type, drawId, glxConfig)) {
|
||||
pDraw, type, glxDrawId, glxConfig)) {
|
||||
xfree(private);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,10 +134,12 @@ struct __GLXscreen {
|
|||
__GLXconfig *modes,
|
||||
__GLXcontext *shareContext);
|
||||
|
||||
__GLXdrawable *(*createDrawable)(__GLXscreen *context,
|
||||
__GLXdrawable *(*createDrawable)(ClientPtr client,
|
||||
__GLXscreen *context,
|
||||
DrawablePtr pDraw,
|
||||
int type,
|
||||
XID drawId,
|
||||
int type,
|
||||
XID glxDrawId,
|
||||
__GLXconfig *modes);
|
||||
int (*swapInterval) (__GLXdrawable *drawable,
|
||||
int interval);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include <errno.h>
|
||||
#include <xf86drm.h>
|
||||
#include "xf86Module.h"
|
||||
#include "list.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "windowstr.h"
|
||||
#include "dixstruct.h"
|
||||
|
|
@ -48,15 +49,20 @@
|
|||
CARD8 dri2_major; /* version of DRI2 supported by DDX */
|
||||
CARD8 dri2_minor;
|
||||
|
||||
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;
|
||||
DrawablePtr drawable;
|
||||
struct list reference_list;
|
||||
int width;
|
||||
int height;
|
||||
DRI2BufferPtr *buffers;
|
||||
|
|
@ -73,9 +79,9 @@ typedef struct _DRI2Drawable {
|
|||
int swap_limit; /* for N-buffering */
|
||||
} DRI2DrawableRec, *DRI2DrawablePtr;
|
||||
|
||||
typedef struct _DRI2Screen *DRI2ScreenPtr;
|
||||
|
||||
typedef struct _DRI2Screen {
|
||||
ScreenPtr screen;
|
||||
int refcnt;
|
||||
unsigned int numDrivers;
|
||||
const char **driverNames;
|
||||
const char *deviceName;
|
||||
|
|
@ -101,45 +107,33 @@ DRI2GetScreen(ScreenPtr pScreen)
|
|||
static DRI2DrawablePtr
|
||||
DRI2GetDrawable(DrawablePtr pDraw)
|
||||
{
|
||||
WindowPtr pWin;
|
||||
PixmapPtr pPixmap;
|
||||
WindowPtr pWin;
|
||||
PixmapPtr pPixmap;
|
||||
|
||||
if (!pDraw)
|
||||
return NULL;
|
||||
|
||||
if (pDraw->type == DRAWABLE_WINDOW)
|
||||
{
|
||||
if (pDraw->type == DRAWABLE_WINDOW) {
|
||||
pWin = (WindowPtr) pDraw;
|
||||
return dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
pPixmap = (PixmapPtr) pDraw;
|
||||
return dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
DRI2CreateDrawable(DrawablePtr pDraw)
|
||||
static DRI2DrawablePtr
|
||||
DRI2AllocateDrawable(DrawablePtr pDraw)
|
||||
{
|
||||
DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
|
||||
WindowPtr pWin;
|
||||
PixmapPtr pPixmap;
|
||||
DRI2DrawablePtr pPriv;
|
||||
CARD64 ust;
|
||||
|
||||
pPriv = DRI2GetDrawable(pDraw);
|
||||
if (pPriv != NULL)
|
||||
{
|
||||
pPriv->refCount++;
|
||||
return Success;
|
||||
}
|
||||
WindowPtr pWin;
|
||||
PixmapPtr pPixmap;
|
||||
|
||||
pPriv = xalloc(sizeof *pPriv);
|
||||
if (pPriv == NULL)
|
||||
return BadAlloc;
|
||||
return NULL;
|
||||
|
||||
pPriv->refCount = 1;
|
||||
pPriv->dri2_screen = ds;
|
||||
pPriv->drawable = pDraw;
|
||||
pPriv->width = pDraw->width;
|
||||
pPriv->height = pDraw->height;
|
||||
pPriv->buffers = NULL;
|
||||
|
|
@ -157,44 +151,131 @@ DRI2CreateDrawable(DrawablePtr pDraw)
|
|||
pPriv->swap_limit = 1; /* default to double buffering */
|
||||
pPriv->last_swap_msc = 0;
|
||||
pPriv->last_swap_ust = 0;
|
||||
list_init(&pPriv->reference_list);
|
||||
|
||||
if (pDraw->type == DRAWABLE_WINDOW)
|
||||
{
|
||||
if (pDraw->type == DRAWABLE_WINDOW) {
|
||||
pWin = (WindowPtr) pDraw;
|
||||
dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, pPriv);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
pPixmap = (PixmapPtr) pDraw;
|
||||
dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, pPriv);
|
||||
}
|
||||
|
||||
return pPriv;
|
||||
}
|
||||
|
||||
typedef struct DRI2DrawableRefRec {
|
||||
XID id;
|
||||
XID dri2_id;
|
||||
struct list link;
|
||||
} DRI2DrawableRefRec, *DRI2DrawableRefPtr;
|
||||
|
||||
static DRI2DrawableRefPtr
|
||||
DRI2LookupDrawableRef(DRI2DrawablePtr pPriv, XID id)
|
||||
{
|
||||
DRI2DrawableRefPtr ref;
|
||||
|
||||
list_for_each_entry(ref, &pPriv->reference_list, link) {
|
||||
if (ref->id == id)
|
||||
return ref;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
DRI2AddDrawableRef(DRI2DrawablePtr pPriv, XID id, XID dri2_id)
|
||||
{
|
||||
DRI2DrawableRefPtr ref;
|
||||
|
||||
ref = malloc(sizeof *ref);
|
||||
if (ref == NULL)
|
||||
return BadAlloc;
|
||||
|
||||
if (!AddResource(dri2_id, dri2DrawableRes, pPriv))
|
||||
return BadAlloc;
|
||||
if (!DRI2LookupDrawableRef(pPriv, id))
|
||||
if (!AddResource(id, dri2DrawableRes, pPriv))
|
||||
return BadAlloc;
|
||||
|
||||
ref->id = id;
|
||||
ref->dri2_id = dri2_id;
|
||||
list_add(&ref->link, &pPriv->reference_list);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
static void
|
||||
DRI2FreeDrawable(DrawablePtr pDraw)
|
||||
int
|
||||
DRI2CreateDrawable(ClientPtr client, DrawablePtr pDraw, XID id)
|
||||
{
|
||||
DRI2DrawablePtr pPriv;
|
||||
WindowPtr pWin;
|
||||
PixmapPtr pPixmap;
|
||||
XID dri2_id;
|
||||
int rc;
|
||||
|
||||
pPriv = DRI2GetDrawable(pDraw);
|
||||
if (pPriv == NULL)
|
||||
return;
|
||||
pPriv = DRI2AllocateDrawable(pDraw);
|
||||
if (pPriv == NULL)
|
||||
return BadAlloc;
|
||||
|
||||
dri2_id = FakeClientID(client->index);
|
||||
rc = DRI2AddDrawableRef(pPriv, id, dri2_id);
|
||||
if (rc != Success)
|
||||
return rc;
|
||||
|
||||
xfree(pPriv);
|
||||
return Success;
|
||||
}
|
||||
|
||||
if (pDraw->type == DRAWABLE_WINDOW)
|
||||
{
|
||||
static int DRI2DrawableGone(pointer p, XID id)
|
||||
{
|
||||
DRI2DrawablePtr pPriv = p;
|
||||
DRI2ScreenPtr ds = pPriv->dri2_screen;
|
||||
DRI2DrawableRefPtr ref, next;
|
||||
WindowPtr pWin;
|
||||
PixmapPtr pPixmap;
|
||||
DrawablePtr pDraw;
|
||||
int i;
|
||||
|
||||
list_for_each_entry_safe(ref, next, &pPriv->reference_list, link) {
|
||||
if (ref->dri2_id == id) {
|
||||
list_del(&ref->link);
|
||||
/* If this was the last ref under this X drawable XID,
|
||||
* unregister the X drawable resource. */
|
||||
if (!DRI2LookupDrawableRef(pPriv, ref->id))
|
||||
FreeResourceByType(ref->id, dri2DrawableRes, TRUE);
|
||||
free(ref);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ref->id == id) {
|
||||
list_del(&ref->link);
|
||||
FreeResourceByType(ref->dri2_id, dri2DrawableRes, TRUE);
|
||||
free(ref);
|
||||
}
|
||||
}
|
||||
|
||||
if (!list_is_empty(&pPriv->reference_list))
|
||||
return Success;
|
||||
|
||||
pDraw = pPriv->drawable;
|
||||
if (pDraw->type == DRAWABLE_WINDOW) {
|
||||
pWin = (WindowPtr) pDraw;
|
||||
dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
pPixmap = (PixmapPtr) pDraw;
|
||||
dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, NULL);
|
||||
}
|
||||
|
||||
if (pPriv->buffers != NULL) {
|
||||
for (i = 0; i < pPriv->bufferCount; i++)
|
||||
(*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
|
||||
|
||||
xfree(pPriv->buffers);
|
||||
}
|
||||
|
||||
xfree(pPriv);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -506,9 +587,6 @@ DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw, int frame,
|
|||
pPriv->blockedClient = NULL;
|
||||
pPriv->blockedOnMsc = FALSE;
|
||||
|
||||
/* If there's still a swap pending, let DRI2SwapComplete free it */
|
||||
if (pPriv->refCount == 0 && pPriv->swapsPending == 0)
|
||||
DRI2FreeDrawable(pDraw);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -576,13 +654,6 @@ DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int frame,
|
|||
pPriv->last_swap_ust = ust;
|
||||
|
||||
DRI2WakeClient(client, pDraw, frame, tv_sec, tv_usec);
|
||||
|
||||
/*
|
||||
* It's normal for the app to have exited with a swap outstanding, but
|
||||
* don't free the drawable until they're all complete.
|
||||
*/
|
||||
if (pPriv->swapsPending == 0 && pPriv->refCount == 0)
|
||||
DRI2FreeDrawable(pDraw);
|
||||
}
|
||||
|
||||
Bool
|
||||
|
|
@ -765,7 +836,7 @@ DRI2WaitMSC(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
|
|||
Bool ret;
|
||||
|
||||
pPriv = DRI2GetDrawable(pDraw);
|
||||
if (pPriv == NULL || pPriv->refCount == 0)
|
||||
if (pPriv == NULL)
|
||||
return BadDrawable;
|
||||
|
||||
/* Old DDX just completes immediately */
|
||||
|
|
@ -788,7 +859,7 @@ DRI2WaitSBC(ClientPtr client, DrawablePtr pDraw, CARD64 target_sbc)
|
|||
DRI2DrawablePtr pPriv;
|
||||
|
||||
pPriv = DRI2GetDrawable(pDraw);
|
||||
if (pPriv == NULL || pPriv->refCount == 0)
|
||||
if (pPriv == NULL)
|
||||
return BadDrawable;
|
||||
|
||||
/* target_sbc == 0 means to block until all pending swaps are
|
||||
|
|
@ -813,36 +884,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 or wait 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 && !pPriv->blockedClient)
|
||||
DRI2FreeDrawable(pDraw);
|
||||
}
|
||||
|
||||
Bool
|
||||
DRI2HasSwapControl(ScreenPtr pScreen)
|
||||
{
|
||||
|
|
@ -903,6 +944,7 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
|
|||
if (!ds)
|
||||
return FALSE;
|
||||
|
||||
ds->screen = pScreen;
|
||||
ds->fd = info->fd;
|
||||
ds->deviceName = info->deviceName;
|
||||
dri2_major = 1;
|
||||
|
|
@ -974,6 +1016,8 @@ DRI2Setup(pointer module, pointer opts, int *errmaj, int *errmin)
|
|||
{
|
||||
static Bool setupDone = FALSE;
|
||||
|
||||
dri2DrawableRes = CreateNewResourceType(DRI2DrawableGone, "DRI2Drawable");
|
||||
|
||||
if (!setupDone)
|
||||
{
|
||||
setupDone = TRUE;
|
||||
|
|
|
|||
|
|
@ -198,7 +198,8 @@ extern _X_EXPORT Bool DRI2Connect(ScreenPtr pScreen,
|
|||
|
||||
extern _X_EXPORT Bool DRI2Authenticate(ScreenPtr pScreen, drm_magic_t magic);
|
||||
|
||||
extern _X_EXPORT int DRI2CreateDrawable(DrawablePtr pDraw);
|
||||
extern _X_EXPORT int DRI2CreateDrawable(ClientPtr client,
|
||||
DrawablePtr pDraw, XID id);
|
||||
|
||||
extern _X_EXPORT void DRI2DestroyDrawable(DrawablePtr pDraw);
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@
|
|||
#include "xf86Module.h"
|
||||
|
||||
static ExtensionEntry *dri2Extension;
|
||||
static RESTYPE dri2DrawableRes;
|
||||
|
||||
static Bool
|
||||
validDrawable(ClientPtr client, XID drawable, Mask access_mode,
|
||||
|
|
@ -168,15 +167,10 @@ ProcDRI2CreateDrawable(ClientPtr client)
|
|||
&pDrawable, &status))
|
||||
return status;
|
||||
|
||||
status = DRI2CreateDrawable(pDrawable);
|
||||
status = DRI2CreateDrawable(client, pDrawable, stuff->drawable);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -617,25 +609,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,
|
||||
|
|
|
|||
|
|
@ -94,4 +94,10 @@ list_is_empty(struct list *head)
|
|||
&pos->member != (head); \
|
||||
pos = __container_of(pos->member.next, pos, member))
|
||||
|
||||
#define list_for_each_entry_safe(pos, next, head, member) \
|
||||
for (pos = __container_of((head)->next, pos, member), \
|
||||
next = __container_of(pos->member.next, pos, member); \
|
||||
&pos->member != (head); \
|
||||
pos = next, next = __container_of(next->member.next, next, member))
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue