[PATCHv10 4/5] dri2: Support the DRI2InvalidateBuffers event.
Peter Hutterer
peter.hutterer at who-t.net
Thu Mar 4 21:15:39 PST 2010
On Mon, Mar 01, 2010 at 08:19:44PM +0100, Francisco Jerez wrote:
> Bumps the supported DRI2 protocol version.
>
> Signed-off-by: Francisco Jerez <currojerez at riseup.net>
> ---
> v10: Move resource allocation to dri2ext.c.
>
> configure.ac | 2 +-
> hw/xfree86/dri2/dri2.c | 122 +++++++++++++++++++++++++++++++++++++++++++
> hw/xfree86/dri2/dri2.h | 6 ++
> hw/xfree86/dri2/dri2ext.c | 75 ++++++++++++++++++++++++++-
> include/protocol-versions.h | 2 +-
> 5 files changed, 204 insertions(+), 3 deletions(-)
>
[...]
> +static void
> +DRI2ConfigNotify(WindowPtr pWin, int x, int y, int w, int h, int bw,
> + WindowPtr pSib)
> +{
> + DrawablePtr pDraw = (DrawablePtr)pWin;
> + ScreenPtr pScreen = pDraw->pScreen;
> + DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
> + DRI2DrawablePtr dd = DRI2GetDrawable(pDraw);
> +
> + if (ds->ConfigNotify) {
> + UNWRAP(pScreen, ds, ConfigNotify);
> + (*pScreen->ConfigNotify)(pWin, x, y, w, h, bw, pSib);
> + WRAP(pScreen, ds, ConfigNotify, DRI2ConfigNotify);
> + }
I don't think this is correct just yet. You're always forcing
DRI2ConfigNotify back after the wrap. What you should be doing though is
popping back whatever was there before. Otherwise, having a different
nesting order will screw up the wrapping code.
See 664ac92d8bbe956dd6fd80fac5dc3161028803b2 for a case where this has
bitten us once already. this may not be possible with the current code, but
better be safe than sorry.
> +
> + if (dd && (dd->width != w || dd->height != h))
> + DRI2InvalidateDrawable(pDraw);
> +}
> +
> Bool
> DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
> {
> @@ -869,6 +989,8 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
>
> dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds);
>
> + WRAP(pScreen, ds, ConfigNotify, DRI2ConfigNotify);
this one is fine, since you're initializing it here.
Cheers,
Peter
> +
> xf86DrvMsg(pScreen->myNum, X_INFO, "[DRI2] Setup complete\n");
> for (i = 0; i < sizeof(driverTypeNames) / sizeof(driverTypeNames[0]); i++) {
> if (i < ds->numDrivers && ds->driverNames[i]) {
> diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
> index 1c8626b..1d5190f 100644
> --- a/hw/xfree86/dri2/dri2.h
> +++ b/hw/xfree86/dri2/dri2.h
> @@ -265,4 +265,10 @@ extern _X_EXPORT void DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw,
> int frame, unsigned int tv_sec,
> unsigned int tv_usec);
>
> +extern _X_EXPORT int DRI2TrackClient(DrawablePtr pDraw, int id,
> + void (*invalidate)(DrawablePtr, void *),
> + void (*destroy)(DrawablePtr, void *),
> + void *priv);
> +extern _X_EXPORT void DRI2UntrackClient(DrawablePtr pDraw, int id);
> +
> #endif
> diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
> index bd92fd3..5644fe5 100644
> --- a/hw/xfree86/dri2/dri2ext.c
> +++ b/hw/xfree86/dri2/dri2ext.c
> @@ -52,6 +52,7 @@
>
> static ExtensionEntry *dri2Extension;
> static RESTYPE dri2DrawableRes;
> +static RESTYPE dri2ClientRefRes;
>
> static Bool
> validDrawable(ClientPtr client, XID drawable, Mask access_mode,
> @@ -197,6 +198,60 @@ ProcDRI2DestroyDrawable(ClientPtr client)
> return client->noClientException;
> }
>
> +static void
> +DRI2InvalidateEvent(DrawablePtr pDraw, void *priv)
> +{
> + XID *id = priv;
> + ClientPtr client = clients[CLIENT_ID(*id)];
> + xDRI2InvalidateBuffers event;
> +
> + if (!client || client->clientGone)
> + return;
> +
> + event.type = DRI2EventBase + DRI2_InvalidateBuffers;
> + event.sequenceNumber = client->sequence;
> + event.drawable = pDraw->id;
> +
> + WriteEventsToClient(client, 1, (xEvent *)&event);
> +}
> +
> +static void
> +DRI2InvalidateDestroy(DrawablePtr pDraw, void *priv)
> +{
> + XID *id = priv;
> +
> + FreeResource(*id, dri2ClientRefRes);
> + xfree(id);
> +}
> +
> +static int
> +track_client(ClientPtr client, DrawablePtr pDraw)
> +{
> + XID *id;
> + int ret = BadAlloc;
> +
> + id = xalloc(sizeof(*id));
> + if (!id)
> + goto fail;
> +
> + /* Allocate a new resource for the client. */
> + *id = FakeClientID(client->index);
> + if (!AddResource(*id, dri2ClientRefRes, pDraw))
> + goto fail;
> +
> + ret = DRI2TrackClient(pDraw, client->index, DRI2InvalidateEvent,
> + DRI2InvalidateDestroy, id);
> + if (ret)
> + goto fail;
> +
> + return Success;
> +
> +fail:
> + if (id)
> + DRI2InvalidateDestroy(pDraw, id);
> +
> + return ret;
> +}
>
> static void
> send_buffers_reply(ClientPtr client, DrawablePtr pDrawable,
> @@ -266,6 +321,9 @@ ProcDRI2GetBuffers(ClientPtr client)
> buffers = DRI2GetBuffers(pDrawable, &width, &height,
> attachments, stuff->count, &count);
>
> + status = track_client(client, pDrawable);
> + if (status)
> + return status;
>
> send_buffers_reply(client, pDrawable, buffers, count, width, height);
>
> @@ -293,6 +351,10 @@ ProcDRI2GetBuffersWithFormat(ClientPtr client)
> buffers = DRI2GetBuffersWithFormat(pDrawable, &width, &height,
> attachments, stuff->count, &count);
>
> + status = track_client(client, pDrawable);
> + if (status)
> + return status;
> +
> send_buffers_reply(client, pDrawable, buffers, count, width, height);
>
> return client->noClientException;
> @@ -629,16 +691,27 @@ static int DRI2DrawableGone(pointer p, XID id)
> return Success;
> }
>
> +static int
> +DRI2ClientRefGone(pointer p, XID id)
> +{
> + DRI2UntrackClient(p, CLIENT_ID(id));
> + return Success;
> +}
> +
> int DRI2EventBase;
>
> static void
> DRI2ExtensionInit(void)
> {
> dri2DrawableRes = CreateNewResourceType(DRI2DrawableGone, "DRI2Drawable");
> -
> if (!dri2DrawableRes)
> return;
>
> + dri2ClientRefRes =
> + CreateNewResourceType(DRI2ClientRefGone, "DRI2ClientRef");
> + if (!dri2ClientRefRes)
> + return;
> +
> dri2Extension = AddExtension(DRI2_NAME,
> DRI2NumberEvents,
> DRI2NumberErrors,
> diff --git a/include/protocol-versions.h b/include/protocol-versions.h
> index c74b7fa..c425eef 100644
> --- a/include/protocol-versions.h
> +++ b/include/protocol-versions.h
> @@ -53,7 +53,7 @@
>
> /* DRI2 */
> #define SERVER_DRI2_MAJOR_VERSION 1
> -#define SERVER_DRI2_MINOR_VERSION 2
> +#define SERVER_DRI2_MINOR_VERSION 3
>
> /* Generic event extension */
> #define SERVER_GE_MAJOR_VERSION 1
> --
> 1.6.4.4
More information about the xorg-devel
mailing list