On Thu, 2011-02-03 at 19:48 +0200, Pauli wrote: > From: Pauli Nieminen <[email protected]> > > DRI2 swaps may complete after Drawable has been destroyed. This causes > memory management problems as DRI2 internal state is tighly coupled with > Drawable. > > DRI2DrawablePtr can be used to access DRI2 functionality. This provides > option that DRI2 drawable can live longer than underlying Drawable. > > Signed-off-by: Pauli Nieminen <[email protected]> > --- > glx/glxdri2.c | 23 +++++--- > hw/xfree86/dri2/dri2.c | 131 > +++++++++++++++++---------------------------- > hw/xfree86/dri2/dri2.h | 47 ++++++++++++----- > hw/xfree86/dri2/dri2ext.c | 116 +++++++++++++++++++++++++--------------- > 4 files changed, 170 insertions(+), 147 deletions(-) > > diff --git a/glx/glxdri2.c b/glx/glxdri2.c > index 8d21c93..027615a 100644 > --- a/glx/glxdri2.c > +++ b/glx/glxdri2.c > @@ -88,6 +88,7 @@ struct __GLXDRIdrawable { > __GLXdrawable base; > __DRIdrawable *driDrawable; > __GLXDRIscreen *screen; > + DRI2DrawablePtr pDRI2Draw; > > /* Dimensions as last reported by DRI2GetBuffers. */ > int width; > @@ -123,7 +124,7 @@ __glXDRIdrawableCopySubBuffer(__GLXdrawable *drawable, > box.y2 = private->height - y; > RegionInit(®ion, &box, 0); > > - DRI2CopyRegion(drawable->pDraw, ®ion, > + DRI2CopyRegion(private->pDRI2Draw, ®ion, > DRI2BufferFrontLeft, DRI2BufferBackLeft); > } > > @@ -140,7 +141,7 @@ __glXDRIdrawableWaitX(__GLXdrawable *drawable) > box.y2 = private->height; > RegionInit(®ion, &box, 0); > > - DRI2CopyRegion(drawable->pDraw, ®ion, > + DRI2CopyRegion(private->pDRI2Draw, ®ion, > DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft); > } > > @@ -157,7 +158,7 @@ __glXDRIdrawableWaitGL(__GLXdrawable *drawable) > box.y2 = private->height; > RegionInit(®ion, &box, 0); > > - DRI2CopyRegion(drawable->pDraw, ®ion, > + DRI2CopyRegion(private->pDRI2Draw, ®ion, > DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft); > } > > @@ -220,7 +221,7 @@ __glXDRIdrawableSwapBuffers(ClientPtr client, > __GLXdrawable *drawable) > (*screen->flush->flushInvalidate)(priv->driDrawable); > #endif > > - if (DRI2SwapBuffers(client, drawable->pDraw, 0, 0, 0, &unused, > + if (DRI2SwapBuffers(client, priv->pDRI2Draw, 0, 0, 0, &unused, > __glXdriSwapEvent, drawable->pDraw) != Success) > return FALSE; > > @@ -230,10 +231,11 @@ __glXDRIdrawableSwapBuffers(ClientPtr client, > __GLXdrawable *drawable) > static int > __glXDRIdrawableSwapInterval(__GLXdrawable *drawable, int interval) > { > + __GLXDRIdrawable *priv = (__GLXDRIdrawable *) drawable; > if (interval <= 0) /* || interval > BIGNUM? */ > return GLX_BAD_VALUE; > > - DRI2SwapInterval(drawable->pDraw, interval); > + DRI2SwapInterval(priv->pDRI2Draw, interval); > > return 0; > } > @@ -300,7 +302,8 @@ static Bool > __glXDRIcontextWait(__GLXcontext *baseContext, > __GLXclientState *cl, int *error) > { > - if (DRI2WaitSwap(cl->client, baseContext->drawPriv->pDraw)) { > + __GLXDRIdrawable *priv = (__GLXDRIdrawable *) baseContext->drawPriv; > + if (DRI2WaitSwap(cl->client, priv->pDRI2Draw)) { > *error = cl->client->noClientException; > return TRUE; > } > @@ -428,7 +431,7 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen, > } > > static void > -__glXDRIinvalidateBuffers(DrawablePtr pDraw, void *priv) > +__glXDRIinvalidateBuffers(DRI2DrawablePtr pDRI2Draw, void *priv, XID id) > { > #if __DRI2_FLUSH_VERSION >= 3 > __GLXDRIdrawable *private = priv; > @@ -475,6 +478,8 @@ __glXDRIscreenCreateDrawable(ClientPtr client, > return NULL; > } > > + private->pDRI2Draw = DRI2GetDrawable(pDraw); > + > private->driDrawable = > (*driScreen->dri2->createNewDrawable)(driScreen->driScreen, > config->driConfig, private); > @@ -493,7 +498,7 @@ dri2GetBuffers(__DRIdrawable *driDrawable, > int i; > int j; > > - buffers = DRI2GetBuffers(private->base.pDraw, > + buffers = DRI2GetBuffers(private->pDRI2Draw, > width, height, attachments, count, out_count); > if (*out_count > MAX_DRAWABLE_BUFFERS) { > *out_count = 0; > @@ -537,7 +542,7 @@ dri2GetBuffersWithFormat(__DRIdrawable *driDrawable, > int i; > int j = 0; > > - buffers = DRI2GetBuffersWithFormat(private->base.pDraw, > + buffers = DRI2GetBuffersWithFormat(private->pDRI2Draw, > width, height, attachments, count, > out_count); > if (*out_count > MAX_DRAWABLE_BUFFERS) { > diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c > index 66d217c..91ae1a0 100644 > --- a/hw/xfree86/dri2/dri2.c > +++ b/hw/xfree86/dri2/dri2.c > @@ -60,7 +60,7 @@ static DevPrivateKeyRec dri2WindowPrivateKeyRec; > static DevPrivateKeyRec dri2PixmapPrivateKeyRec; > #define dri2PixmapPrivateKey (&dri2PixmapPrivateKeyRec) > > -static RESTYPE dri2DrawableRes; > +RESTYPE dri2DrawableRes; > > typedef struct _DRI2Screen *DRI2ScreenPtr; > > @@ -83,7 +83,7 @@ typedef struct _DRI2Drawable { > CARD64 last_swap_ust; /* ust at completion of most recent > swap */ > int swap_limit; /* for N-buffering */ > unsigned long serialNumber; > -} DRI2DrawableRec, *DRI2DrawablePtr; > +} DRI2DrawableRec; > > typedef struct _DRI2Screen { > ScreenPtr screen; > @@ -113,7 +113,7 @@ DRI2GetScreen(ScreenPtr pScreen) > return dixLookupPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey); > } > > -static DRI2DrawablePtr > +DRI2DrawablePtr > DRI2GetDrawable(DrawablePtr pDraw) > { > WindowPtr pWin; > @@ -131,6 +131,12 @@ DRI2GetDrawable(DrawablePtr pDraw) > } > } > > +DrawablePtr > +DRI2DrawableGetDrawable(DRI2DrawablePtr pPriv) > +{ > + return pPriv->drawable; > +} > + > static unsigned long > DRI2DrawableSerial(DrawablePtr pDraw) > { > @@ -271,13 +277,9 @@ DRI2CreateDrawable(ClientPtr client, DrawablePtr pDraw, > XID id, > } > > int > -DRI2DestroyDrawable(ClientPtr client, DrawablePtr pDraw, XID id) > +DRI2DestroyDrawable(ClientPtr client, DRI2DrawablePtr pPriv, XID id) > { > DRI2DrawableRefPtr ref; > - DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw); > - > - if (!pPriv) > - return BadDrawable; > > ref = DRI2LookupClientDrawableRef(pPriv, client, id); > > @@ -408,12 +410,12 @@ update_dri2_drawable_buffers(DRI2DrawablePtr pPriv, > DrawablePtr pDraw, > } > > static DRI2BufferPtr * > -do_get_buffers(DrawablePtr pDraw, int *width, int *height, > +do_get_buffers(DRI2DrawablePtr pPriv, int *width, int *height, > unsigned int *attachments, int count, int *out_count, > int has_format) > { > - DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen); > - DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw); > + DrawablePtr pDraw = pPriv->drawable; > + DRI2ScreenPtr ds = pPriv->dri2_screen; > DRI2BufferPtr *buffers; > int need_real_front = 0; > int need_fake_front = 0; > @@ -423,7 +425,7 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height, > int buffers_changed = 0; > int i; > > - if (!pPriv) { > + if (!pDraw) { > *width = pDraw->width; > *height = pDraw->height; > *out_count = 0; > @@ -517,7 +519,7 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height, > box.y2 = pPriv->height; > RegionInit(®ion, &box, 0); > > - DRI2CopyRegion(pDraw, ®ion, DRI2BufferFakeFrontLeft, > + DRI2CopyRegion(pPriv, ®ion, DRI2BufferFakeFrontLeft, > DRI2BufferFrontLeft); > } > > @@ -541,32 +543,28 @@ err_out: > } > > DRI2BufferPtr * > -DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height, > +DRI2GetBuffers(DRI2DrawablePtr pPriv, int *width, int *height, > unsigned int *attachments, int count, int *out_count) > { > - return do_get_buffers(pDraw, width, height, attachments, count, > + return do_get_buffers(pPriv, width, height, attachments, count, > out_count, FALSE); > } > > DRI2BufferPtr * > -DRI2GetBuffersWithFormat(DrawablePtr pDraw, int *width, int *height, > +DRI2GetBuffersWithFormat(DRI2DrawablePtr pPriv, int *width, int *height, > unsigned int *attachments, int count, int *out_count) > { > - return do_get_buffers(pDraw, width, height, attachments, count, > + return do_get_buffers(pPriv, width, height, attachments, count, > out_count, TRUE); > } > > static void > -DRI2InvalidateDrawable(DrawablePtr pDraw) > +DRI2InvalidateDrawable(DRI2DrawablePtr pPriv) > { > - DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw); > DRI2DrawableRefPtr ref; > > - if (!pPriv) > - return; > - > list_for_each_entry(ref, &pPriv->reference_list, link) > - ref->invalidate(pDraw, ref->priv); > + ref->invalidate(pPriv, ref->priv, ref->id); > } > > /* > @@ -577,14 +575,8 @@ DRI2InvalidateDrawable(DrawablePtr pDraw) > * comes in (see __glXDRIcontextWait()). > */ > Bool > -DRI2ThrottleClient(ClientPtr client, DrawablePtr pDraw) > +DRI2ThrottleClient(ClientPtr client, DRI2DrawablePtr pPriv) > { > - DRI2DrawablePtr pPriv; > - > - pPriv = DRI2GetDrawable(pDraw); > - if (pPriv == NULL) > - return FALSE; > - > /* Throttle to swap limit */ > if ((pPriv->swapsPending >= pPriv->swap_limit) && > !pPriv->blockedClient) { > @@ -621,16 +613,15 @@ DRI2BlockClient(ClientPtr client, DrawablePtr pDraw) > } > > int > -DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion, > +DRI2CopyRegion(DRI2DrawablePtr pPriv, RegionPtr pRegion, > unsigned int dest, unsigned int src) > { > - DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen); > - DRI2DrawablePtr pPriv; > + DrawablePtr pDraw = pPriv->drawable; > + DRI2ScreenPtr ds = pPriv->dri2_screen; > DRI2BufferPtr pDestBuffer, pSrcBuffer; > int i; > > - pPriv = DRI2GetDrawable(pDraw); > - if (pPriv == NULL) > + if (pDraw == NULL) > return BadDrawable; > > pDestBuffer = NULL; > @@ -713,14 +704,12 @@ DRI2WaitMSCComplete(ClientPtr client, DrawablePtr > pDraw, int frame, > } > > static void > -DRI2WakeClient(ClientPtr client, DrawablePtr pDraw, int frame, > +DRI2WakeClient(ClientPtr client, DRI2DrawablePtr pPriv, int frame, > unsigned int tv_sec, unsigned int tv_usec) > { > - ScreenPtr pScreen = pDraw->pScreen; > - DRI2DrawablePtr pPriv; > + ScreenPtr pScreen = pPriv->dri2_screen->screen; > > - pPriv = DRI2GetDrawable(pDraw); > - if (pPriv == NULL) { > + if (pPriv->drawable == NULL) { > xf86DrvMsg(pScreen->myNum, X_ERROR, > "[DRI2] %s: bad drawable\n", __func__); > return; > @@ -776,7 +765,7 @@ DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int > frame, > box.x2 = pDraw->width; > box.y2 = pDraw->height; > RegionInit(®ion, &box, 0); > - DRI2CopyRegion(pDraw, ®ion, DRI2BufferFakeFrontLeft, > + DRI2CopyRegion(pPriv, ®ion, DRI2BufferFakeFrontLeft, > DRI2BufferFrontLeft); > > ust = ((CARD64)tv_sec * 1000000) + tv_usec; > @@ -786,14 +775,12 @@ DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, > int frame, > pPriv->last_swap_msc = frame; > pPriv->last_swap_ust = ust; > > - DRI2WakeClient(client, pDraw, frame, tv_sec, tv_usec); > + DRI2WakeClient(client, pPriv, frame, tv_sec, tv_usec); > } > > Bool > -DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable) > +DRI2WaitSwap(ClientPtr client, DRI2DrawablePtr pPriv) > { > - DRI2DrawablePtr pPriv = DRI2GetDrawable(pDrawable); > - > /* If we're currently waiting for a swap on this drawable, reset > * the request and suspend the client. We only support one > * blocked client per drawable. */ > @@ -809,19 +796,18 @@ DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable) > } > > int > -DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc, > +DRI2SwapBuffers(ClientPtr client, DRI2DrawablePtr pPriv, CARD64 target_msc, > CARD64 divisor, CARD64 remainder, CARD64 *swap_target, > DRI2SwapEventPtr func, void *data) > { > - ScreenPtr pScreen = pDraw->pScreen; > - DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen); > - DRI2DrawablePtr pPriv; > + DrawablePtr pDraw = pPriv->drawable; > + ScreenPtr pScreen = pPriv->dri2_screen->screen; > + DRI2ScreenPtr ds = pPriv->dri2_screen; > DRI2BufferPtr pDestBuffer = NULL, pSrcBuffer = NULL; > int ret, i; > CARD64 ust, current_msc; > > - pPriv = DRI2GetDrawable(pDraw); > - if (pPriv == NULL) { > + if (pDraw == NULL) { > xf86DrvMsg(pScreen->myNum, X_ERROR, > "[DRI2] %s: bad drawable\n", __func__); > return BadDrawable; > @@ -908,37 +894,27 @@ DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, > CARD64 target_msc, > */ > *swap_target = pPriv->swap_count + pPriv->swapsPending; > > - DRI2InvalidateDrawable(pDraw); > + DRI2InvalidateDrawable(pPriv); > > return Success; > } > > void > -DRI2SwapInterval(DrawablePtr pDrawable, int interval) > +DRI2SwapInterval(DRI2DrawablePtr pPriv, int interval) > { > - ScreenPtr pScreen = pDrawable->pScreen; > - DRI2DrawablePtr pPriv = DRI2GetDrawable(pDrawable); > - > - if (pPriv == NULL) { > - xf86DrvMsg(pScreen->myNum, X_ERROR, > - "[DRI2] %s: bad drawable\n", __func__); > - return; > - } > - > /* fixme: check against arbitrary max? */ > pPriv->swap_interval = interval; > } > > int > -DRI2GetMSC(DrawablePtr pDraw, CARD64 *ust, CARD64 *msc, CARD64 *sbc) > +DRI2GetMSC(DRI2DrawablePtr pPriv, CARD64 *ust, CARD64 *msc, CARD64 *sbc) > { > - ScreenPtr pScreen = pDraw->pScreen; > - DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen); > - DRI2DrawablePtr pPriv; > + ScreenPtr pScreen = pPriv->dri2_screen->screen; > + DRI2ScreenPtr ds = pPriv->dri2_screen; > + DrawablePtr pDraw = pPriv->drawable; > Bool ret; > > - pPriv = DRI2GetDrawable(pDraw); > - if (pPriv == NULL) { > + if (pDraw == NULL) { > xf86DrvMsg(pScreen->myNum, X_ERROR, > "[DRI2] %s: bad drawable\n", __func__); > return BadDrawable; > @@ -966,15 +942,14 @@ DRI2GetMSC(DrawablePtr pDraw, CARD64 *ust, CARD64 *msc, > CARD64 *sbc) > } > > int > -DRI2WaitMSC(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc, > +DRI2WaitMSC(ClientPtr client, DRI2DrawablePtr pPriv, CARD64 target_msc, > CARD64 divisor, CARD64 remainder) > { > - DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen); > - DRI2DrawablePtr pPriv; > + DRI2ScreenPtr ds = pPriv->dri2_screen; > + DrawablePtr pDraw = pPriv->drawable; > Bool ret; > > - pPriv = DRI2GetDrawable(pDraw); > - if (pPriv == NULL) > + if (pDraw == NULL) > return BadDrawable; > > /* Old DDX just completes immediately */ > @@ -992,14 +967,8 @@ DRI2WaitMSC(ClientPtr client, DrawablePtr pDraw, CARD64 > target_msc, > } > > int > -DRI2WaitSBC(ClientPtr client, DrawablePtr pDraw, CARD64 target_sbc) > +DRI2WaitSBC(ClientPtr client, DRI2DrawablePtr pPriv, CARD64 target_sbc) > { > - DRI2DrawablePtr pPriv; > - > - pPriv = DRI2GetDrawable(pDraw); > - if (pPriv == NULL) > - return BadDrawable; > - > /* target_sbc == 0 means to block until all pending swaps are > * finished. Recalculate target_sbc to get that behaviour. > */ > @@ -1086,7 +1055,7 @@ DRI2ConfigNotify(WindowPtr pWin, int x, int y, int w, > int h, int bw, > if (!dd || (dd->width == w && dd->height == h)) > return Success; > > - DRI2InvalidateDrawable(pDraw); > + DRI2InvalidateDrawable(DRI2GetDrawable(pDraw)); > return Success; > } > > diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h > index dd63c30..509d4f6 100644 > --- a/hw/xfree86/dri2/dri2.h > +++ b/hw/xfree86/dri2/dri2.h > @@ -46,6 +46,10 @@ typedef struct { > void *driverPrivate; > } DRI2BufferRec, *DRI2BufferPtr; > > +struct _DRI2Drawable; > + > +typedef struct _DRI2Drawable *DRI2DrawablePtr; > + > extern CARD8 dri2_major; /* version of DRI2 supported by DDX */ > extern CARD8 dri2_minor; > > @@ -155,8 +159,9 @@ typedef int > (*DRI2ScheduleWaitMSCProcPtr)(ClientPtr client, > CARD64 divisor, > CARD64 remainder); > > -typedef void (*DRI2InvalidateProcPtr)(DrawablePtr pDraw, > - void *data); > +typedef void (*DRI2InvalidateProcPtr)(DRI2DrawablePtr pPriv, > + void *data, > + XID id); > > /** > * Version of the DRI2InfoRec structure defined in this header > @@ -215,17 +220,17 @@ extern _X_EXPORT int DRI2CreateDrawable(ClientPtr > client, > void *priv); > > extern _X_EXPORT int DRI2DestroyDrawable(ClientPtr client, > - DrawablePtr pDraw, > + DRI2DrawablePtr pPriv, > XID id); > > -extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffers(DrawablePtr pDraw, > +extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffers(DRI2DrawablePtr pPriv, > int *width, > int *height, > unsigned int *attachments, > int count, > int *out_count); > > -extern _X_EXPORT int DRI2CopyRegion(DrawablePtr pDraw, > +extern _X_EXPORT int DRI2CopyRegion(DRI2DrawablePtr pPriv, > RegionPtr pRegion, > unsigned int dest, > unsigned int src); > @@ -248,27 +253,27 @@ extern _X_EXPORT int DRI2CopyRegion(DrawablePtr pDraw, > */ > extern _X_EXPORT void DRI2Version(int *major, int *minor); > > -extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffersWithFormat(DrawablePtr pDraw, > +extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffersWithFormat(DRI2DrawablePtr > pPriv, > int *width, int *height, unsigned int *attachments, int count, > int *out_count); > > -extern _X_EXPORT void DRI2SwapInterval(DrawablePtr pDrawable, int interval); > -extern _X_EXPORT int DRI2SwapBuffers(ClientPtr client, DrawablePtr pDrawable, > +extern _X_EXPORT void DRI2SwapInterval(DRI2DrawablePtr pPriv, int interval); > +extern _X_EXPORT int DRI2SwapBuffers(ClientPtr client, DRI2DrawablePtr pPriv, > CARD64 target_msc, CARD64 divisor, > CARD64 remainder, CARD64 *swap_target, > DRI2SwapEventPtr func, void *data); > -extern _X_EXPORT Bool DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable); > +extern _X_EXPORT Bool DRI2WaitSwap(ClientPtr client, DRI2DrawablePtr pPriv); > > -extern _X_EXPORT int DRI2GetMSC(DrawablePtr pDrawable, CARD64 *ust, > +extern _X_EXPORT int DRI2GetMSC(DRI2DrawablePtr pPriv, CARD64 *ust, > CARD64 *msc, CARD64 *sbc); > -extern _X_EXPORT int DRI2WaitMSC(ClientPtr client, DrawablePtr pDrawable, > +extern _X_EXPORT int DRI2WaitMSC(ClientPtr client, DRI2DrawablePtr pPriv, > CARD64 target_msc, CARD64 divisor, > CARD64 remainder); > extern _X_EXPORT int ProcDRI2WaitMSCReply(ClientPtr client, CARD64 ust, > CARD64 msc, CARD64 sbc); > -extern _X_EXPORT int DRI2WaitSBC(ClientPtr client, DrawablePtr pDraw, > +extern _X_EXPORT int DRI2WaitSBC(ClientPtr client, DRI2DrawablePtr pPriv, > CARD64 target_sbc); > -extern _X_EXPORT Bool DRI2ThrottleClient(ClientPtr client, DrawablePtr > pDraw); > +extern _X_EXPORT Bool DRI2ThrottleClient(ClientPtr client, DRI2DrawablePtr > pPriv); > > extern _X_EXPORT Bool DRI2CanFlip(DrawablePtr pDraw); > > @@ -285,5 +290,21 @@ extern _X_EXPORT void DRI2SwapComplete(ClientPtr client, > DrawablePtr pDraw, > extern _X_EXPORT void DRI2WaitMSCComplete(ClientPtr client, DrawablePtr > pDraw, > int frame, unsigned int tv_sec, > unsigned int tv_usec); > +/** > + * Provides access to DrawablePtr trough DRI2DrawablePtr > + * > + * If Drawable is window and already destroyed return value is NULL. > Otherwise > + * returned pointer is valid DrawablePtr. > + * > + * \param pPriv DRI2 private drawable > + */ > +extern _X_EXPORT DrawablePtr DRI2DrawableGetDrawable(DRI2DrawablePtr pPriv); > > +/** > + * Provides access to DRI2DrawablePtr trough DrawablePtr > + * > + * \param pDraw drawable pointer > + * \return Valid DRI2DrawablePtr if DRI2Drawable exists. Otherwise NULL. > + */ > +extern _X_EXPORT DRI2DrawablePtr DRI2GetDrawable(DrawablePtr pDraw); > #endif > diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c > index c7e6be1..639bbc5 100644 > --- a/hw/xfree86/dri2/dri2ext.c > +++ b/hw/xfree86/dri2/dri2ext.c > @@ -50,6 +50,33 @@ > #include "xf86Module.h" > > static ExtensionEntry *dri2Extension; > +extern RESTYPE dri2DrawableRes; > + > +static Bool > +validDRI2Drawable(ClientPtr client, XID id, Mask access, > + DRI2DrawablePtr *pPriv, int *status) > +{ > + DRI2DrawablePtr pTmp; > + int rc; > + > + if (id == INVALID) { > + *status = BadDrawable; > + return FALSE; > + } > + > + rc = dixLookupResourceByType((pointer*)&pTmp, id, dri2DrawableRes, > client, access); > + > + if (rc == BadValue) { > + *status = BadDrawable; > + return FALSE; > + } > + *status = rc; > + if (rc != Success) > + return FALSE; > + > + *pPriv = pTmp; > + return TRUE; > +} > > static Bool > validDrawable(ClientPtr client, XID drawable, Mask access_mode, > @@ -156,13 +183,13 @@ ProcDRI2Authenticate(ClientPtr client) > } > > static void > -DRI2InvalidateBuffersEvent(DrawablePtr pDraw, void *priv) > +DRI2InvalidateBuffersEvent(DRI2DrawablePtr pPriv, void *priv, XID id) > { > xDRI2InvalidateBuffers event; > ClientPtr client = priv; > > event.type = DRI2EventBase + DRI2_InvalidateBuffers; > - event.drawable = pDraw->id; > + event.drawable = id; > > WriteEventsToClient(client, 1, (xEvent *)&event); > } > @@ -192,30 +219,31 @@ static int > ProcDRI2DestroyDrawable(ClientPtr client) > { > REQUEST(xDRI2DestroyDrawableReq); > - DrawablePtr pDrawable; > + DRI2DrawablePtr pPriv; > int status; > > REQUEST_SIZE_MATCH(xDRI2DestroyDrawableReq); > - if (!validDrawable(client, stuff->drawable, DixRemoveAccess, > - &pDrawable, &status)) > + if (!validDRI2Drawable(client, stuff->drawable, DixRemoveAccess, > + &pPriv, &status)) > return status; > > - return DRI2DestroyDrawable(client, pDrawable, stuff->drawable); > + return DRI2DestroyDrawable(client, pPriv, stuff->drawable); > } > > > static int > -send_buffers_reply(ClientPtr client, DrawablePtr pDrawable, > +send_buffers_reply(ClientPtr client, DRI2DrawablePtr pPriv, > DRI2BufferPtr *buffers, int count, int width, int height) > { > xDRI2GetBuffersReply rep; > int skip = 0; > int i; > + DrawablePtr pDrawable = DRI2DrawableGetDrawable(pPriv); > > if (buffers == NULL) > return BadAlloc; > > - if (pDrawable->type == DRAWABLE_WINDOW) { > + if (!pDrawable || pDrawable->type == DRAWABLE_WINDOW) { > for (i = 0; i < count; i++) { > /* Do not send the real front buffer of a window to the client. > */
The comment doesn't quite make sense at this point of the patch series,
although later patches mean pDrawable can be null IFF the DRI2Drawable
was created from a DRAWABLE_WINDOW.
It might be nice to add that to the comment, otherwise it's not clear
that !pDrawable implies pDrawable->type == DRAWABLE_WINDOW used to be
true.
> @@ -239,7 +267,7 @@ send_buffers_reply(ClientPtr client, DrawablePtr
> pDrawable,
>
> /* Do not send the real front buffer of a window to the client.
> */
> - if ((pDrawable->type == DRAWABLE_WINDOW)
> + if ((!pDrawable || pDrawable->type == DRAWABLE_WINDOW)
> && (buffers[i]->attachment == DRI2BufferFrontLeft)) {
> continue;
> }
> @@ -259,25 +287,25 @@ static int
> ProcDRI2GetBuffers(ClientPtr client)
> {
> REQUEST(xDRI2GetBuffersReq);
> - DrawablePtr pDrawable;
> + DRI2DrawablePtr pPriv;
> DRI2BufferPtr *buffers;
> int status, width, height, count;
> unsigned int *attachments;
>
> REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4);
> - if (!validDrawable(client, stuff->drawable, DixReadAccess |
> DixWriteAccess,
> - &pDrawable, &status))
> + if (!validDRI2Drawable(client, stuff->drawable, DixReadAccess |
> DixWriteAccess,
> + &pPriv, &status))
> return status;
>
> - if (DRI2ThrottleClient(client, pDrawable))
> + if (DRI2ThrottleClient(client, pPriv))
> return Success;
>
> attachments = (unsigned int *) &stuff[1];
> - buffers = DRI2GetBuffers(pDrawable, &width, &height,
> + buffers = DRI2GetBuffers(pPriv, &width, &height,
> attachments, stuff->count, &count);
>
>
> - return send_buffers_reply(client, pDrawable, buffers, count, width,
> height);
> + return send_buffers_reply(client, pPriv, buffers, count, width, height);
>
> }
>
> @@ -285,24 +313,24 @@ static int
> ProcDRI2GetBuffersWithFormat(ClientPtr client)
> {
> REQUEST(xDRI2GetBuffersReq);
> - DrawablePtr pDrawable;
> + DRI2DrawablePtr pPriv;
> DRI2BufferPtr *buffers;
> int status, width, height, count;
> unsigned int *attachments;
>
> REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * (2 * 4));
> - if (!validDrawable(client, stuff->drawable, DixReadAccess |
> DixWriteAccess,
> - &pDrawable, &status))
> + if (!validDRI2Drawable(client, stuff->drawable, DixReadAccess |
> DixWriteAccess,
> + &pPriv, &status))
> return status;
>
> - if (DRI2ThrottleClient(client, pDrawable))
> + if (DRI2ThrottleClient(client, pPriv))
> return Success;
>
> attachments = (unsigned int *) &stuff[1];
> - buffers = DRI2GetBuffersWithFormat(pDrawable, &width, &height,
> + buffers = DRI2GetBuffersWithFormat(pPriv, &width, &height,
> attachments, stuff->count, &count);
>
> - return send_buffers_reply(client, pDrawable, buffers, count, width,
> height);
> + return send_buffers_reply(client, pPriv, buffers, count, width, height);
> }
>
> static int
> @@ -310,19 +338,19 @@ ProcDRI2CopyRegion(ClientPtr client)
> {
> REQUEST(xDRI2CopyRegionReq);
> xDRI2CopyRegionReply rep;
> - DrawablePtr pDrawable;
> + DRI2DrawablePtr pPriv;
> int status;
> RegionPtr pRegion;
>
> REQUEST_SIZE_MATCH(xDRI2CopyRegionReq);
>
> - if (!validDrawable(client, stuff->drawable, DixWriteAccess,
> - &pDrawable, &status))
> + if (!validDRI2Drawable(client, stuff->drawable, DixWriteAccess,
> + &pPriv, &status))
> return status;
>
> VERIFY_REGION(pRegion, stuff->region, client, DixReadAccess);
>
> - status = DRI2CopyRegion(pDrawable, pRegion, stuff->dest, stuff->src);
> + status = DRI2CopyRegion(pPriv, pRegion, stuff->dest, stuff->src);
> if (status != Success)
> return status;
>
> @@ -380,29 +408,29 @@ ProcDRI2SwapBuffers(ClientPtr client)
> {
> REQUEST(xDRI2SwapBuffersReq);
> xDRI2SwapBuffersReply rep;
> - DrawablePtr pDrawable;
> + DRI2DrawablePtr pPriv;
> CARD64 target_msc, divisor, remainder, swap_target;
> int status;
>
> REQUEST_SIZE_MATCH(xDRI2SwapBuffersReq);
>
> - if (!validDrawable(client, stuff->drawable,
> - DixReadAccess | DixWriteAccess, &pDrawable, &status))
> + if (!validDRI2Drawable(client, stuff->drawable,
> + DixReadAccess | DixWriteAccess, &pPriv, &status))
> return status;
>
> /*
> * Ensures an out of control client can't exhaust our swap queue, and
> * also orders swaps.
> */
> - if (DRI2ThrottleClient(client, pDrawable))
> + if (DRI2ThrottleClient(client, pPriv))
> return Success;
>
> target_msc = vals_to_card64(stuff->target_msc_lo, stuff->target_msc_hi);
> divisor = vals_to_card64(stuff->divisor_lo, stuff->divisor_hi);
> remainder = vals_to_card64(stuff->remainder_lo, stuff->remainder_hi);
>
> - status = DRI2SwapBuffers(client, pDrawable, target_msc, divisor,
> remainder,
> - &swap_target, DRI2SwapEvent, pDrawable);
> + status = DRI2SwapBuffers(client, pPriv, target_msc, divisor, remainder,
> + &swap_target, DRI2SwapEvent, pPriv);
> if (status != Success)
> return BadDrawable;
>
> @@ -432,17 +460,17 @@ ProcDRI2GetMSC(ClientPtr client)
> {
> REQUEST(xDRI2GetMSCReq);
> xDRI2MSCReply rep;
> - DrawablePtr pDrawable;
> + DRI2DrawablePtr pPriv;
> CARD64 ust, msc, sbc;
> int status;
>
> REQUEST_SIZE_MATCH(xDRI2GetMSCReq);
>
> - if (!validDrawable(client, stuff->drawable, DixReadAccess, &pDrawable,
> + if (!validDRI2Drawable(client, stuff->drawable, DixReadAccess, &pPriv,
> &status))
> return status;
>
> - status = DRI2GetMSC(pDrawable, &ust, &msc, &sbc);
> + status = DRI2GetMSC(pPriv, &ust, &msc, &sbc);
> if (status != Success)
> return status;
>
> @@ -460,7 +488,7 @@ static int
> ProcDRI2WaitMSC(ClientPtr client)
> {
> REQUEST(xDRI2WaitMSCReq);
> - DrawablePtr pDrawable;
> + DRI2DrawablePtr pPriv;
> CARD64 target, divisor, remainder;
> int status;
>
> @@ -468,7 +496,7 @@ ProcDRI2WaitMSC(ClientPtr client)
>
> REQUEST_SIZE_MATCH(xDRI2WaitMSCReq);
>
> - if (!validDrawable(client, stuff->drawable, DixReadAccess, &pDrawable,
> + if (!validDRI2Drawable(client, stuff->drawable, DixReadAccess, &pPriv,
> &status))
> return status;
>
> @@ -476,7 +504,7 @@ ProcDRI2WaitMSC(ClientPtr client)
> divisor = vals_to_card64(stuff->divisor_lo, stuff->divisor_hi);
> remainder = vals_to_card64(stuff->remainder_lo, stuff->remainder_hi);
>
> - status = DRI2WaitMSC(client, pDrawable, target, divisor, remainder);
> + status = DRI2WaitMSC(client, pPriv, target, divisor, remainder);
> if (status != Success)
> return status;
>
> @@ -502,18 +530,18 @@ static int
> ProcDRI2SwapInterval(ClientPtr client)
> {
> REQUEST(xDRI2SwapIntervalReq);
> - DrawablePtr pDrawable;
> + DRI2DrawablePtr pPriv;
> int status;
>
> /* FIXME: in restart case, client may be gone at this point */
>
> REQUEST_SIZE_MATCH(xDRI2SwapIntervalReq);
>
> - if (!validDrawable(client, stuff->drawable, DixReadAccess |
> DixWriteAccess,
> - &pDrawable, &status))
> + if (!validDRI2Drawable(client, stuff->drawable, DixReadAccess |
> DixWriteAccess,
> + &pPriv, &status))
> return status;
>
> - DRI2SwapInterval(pDrawable, stuff->interval);
> + DRI2SwapInterval(pPriv, stuff->interval);
>
> return Success;
> }
> @@ -522,18 +550,18 @@ static int
> ProcDRI2WaitSBC(ClientPtr client)
> {
> REQUEST(xDRI2WaitSBCReq);
> - DrawablePtr pDrawable;
> + DRI2DrawablePtr pPriv;
> CARD64 target;
> int status;
>
> REQUEST_SIZE_MATCH(xDRI2WaitSBCReq);
>
> - if (!validDrawable(client, stuff->drawable, DixReadAccess, &pDrawable,
> + if (!validDRI2Drawable(client, stuff->drawable, DixReadAccess, &pPriv,
> &status))
> return status;
>
> target = vals_to_card64(stuff->target_sbc_lo, stuff->target_sbc_hi);
> - status = DRI2WaitSBC(client, pDrawable, target);
> + status = DRI2WaitSBC(client, pPriv, target);
>
> return status;
> }
Other than the minor comment quibble,
Reviewed-By: Christopher James Halse Rogers
<[email protected]>
signature.asc
Description: This is a digitally signed message part
_______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
