[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