[PATCH] xserver/glx/dri2: use new GLX/DRI2 swap event types

Jeremy Huddleston jeremyhu at apple.com
Fri May 6 15:41:17 PDT 2011


I believe you want to s/Xmalloc/malloc/

Yes, I can't speak for all the internals of DRI2 since most of that is foreign to me, but from a high level, this looks like the right approach.  As for your specific question about Apple stuff, it's been a while since I touched that... perhaps something we can have a sit-down about during XDC.  So from a high-level point of view:

Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>

but this should also be reviewed by someone who has more understanding of GLX.

--Jeremy

On May 6, 2011, at 14:01, Jesse Barnes wrote:

> On Fri, 6 May 2011 13:00:19 -0700
> Jeremy Huddleston <jeremyhu at apple.com> wrote:
> 
>> Yeah, that looks about right.
>> 
>> This in combination with the latest version of "xserver/glx/dri2: use new GLX/DRI2 swap event types"
>> 
>> Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>
> 
> Ok here's a more complete patch.  It touches GLX and involves drawable
> lifetimes, which I'm not that familiar with, so careful review
> appreciated.  Note the X vs GLX drawable ID switching in the DRI2 event
> handler (DRI2 just deals with X IDs).
> 
> Kristian and Jeremy, is this a good basis for moving the Apple stuff
> over to a client GLX drawable type?
> 
> -- 
> Jesse Barnes, Intel Open Source Technology Center
> 
> From fae63609dd4fd20ccd84d2211787136bb9a1da05 Mon Sep 17 00:00:00 2001
> From: Jesse Barnes <jbarnes at virtuousgeek.org>
> Date: Fri, 6 May 2011 10:31:24 -0700
> Subject: [PATCH] GLX/DRI2: handle swap event swap count wrapping
> 
> Create a new GLX drawable struct to track client related info, and add a
> wrap counter to it drawable and track it as we receive events.  This
> allows us to support the full 64 bits of the event structure we pass to
> the client even though the server only gives us a 32 bit count.
> 
> Signed-off-by: Jesse Barnes <jbarnes at virtuousgeek.org>
> ---
> src/glx/dri2.c        |   12 +++++++++-
> src/glx/glx_pbuffer.c |   14 ++++++++++++
> src/glx/glxclient.h   |   16 +++++++++++++
> src/glx/glxcmds.c     |   57 +++++++++++++++++++++++++++++++++++++++++++++++++
> src/glx/glxext.c      |   16 ++++++++++++-
> 5 files changed, 112 insertions(+), 3 deletions(-)
> 
> diff --git a/src/glx/dri2.c b/src/glx/dri2.c
> index 8654a37..229840d 100644
> --- a/src/glx/dri2.c
> +++ b/src/glx/dri2.c
> @@ -88,6 +88,7 @@ static Bool
> DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire)
> {
>    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
> +   struct glx_drawable *glxDraw;
> 
>    XextCheckExtension(dpy, info, dri2ExtensionName, False);
> 
> @@ -98,6 +99,9 @@ DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire)
>    {
>       GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
>       xDRI2BufferSwapComplete2 *awire = (xDRI2BufferSwapComplete2 *)wire;
> +      __GLXDRIdrawable *pdraw;
> +
> +      pdraw = dri2GetGlxDrawableFromXDrawableId(dpy, awire->drawable);
> 
>       /* Ignore swap events if we're not looking for them */
>       aevent->type = dri2GetSwapEventType(dpy, awire->drawable);
> @@ -124,7 +128,13 @@ DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire)
>       }
>       aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo;
>       aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo;
> -      aevent->sbc = awire->sbc;
> +
> +      glxDraw = GetGLXDrawable(dpy, pdraw->drawable);
> +      if (awire->sbc < glxDraw->lastEventSbc)
> +	 glxDraw->eventSbcWrap += 0x100000000;
> +      glxDraw->lastEventSbc = awire->sbc;
> +      aevent->sbc = awire->sbc + glxDraw->eventSbcWrap;
> +
>       return True;
>    }
> #endif
> diff --git a/src/glx/glx_pbuffer.c b/src/glx/glx_pbuffer.c
> index ec54f1e..420e754 100644
> --- a/src/glx/glx_pbuffer.c
> +++ b/src/glx/glx_pbuffer.c
> @@ -380,7 +380,9 @@ static GLXDrawable
> CreateDrawable(Display *dpy, struct glx_config *config,
>                Drawable drawable, const int *attrib_list, CARD8 glxCode)
> {
> +   struct glx_display *const priv = __glXInitialize(dpy);
>    xGLXCreateWindowReq *req;
> +   struct glx_drawable *glxDraw;
>    CARD32 *data;
>    unsigned int i;
>    CARD8 opcode;
> @@ -395,6 +397,10 @@ CreateDrawable(Display *dpy, struct glx_config *config,
>    if (!opcode)
>       return None;
> 
> +   glxDraw = Xmalloc(sizeof(*glxDraw));
> +   if (!glxDraw)
> +      return None;
> +
>    LockDisplay(dpy);
>    GetReqExtra(GLXCreateWindow, 8 * i, req);
>    data = (CARD32 *) (req + 1);
> @@ -413,6 +419,11 @@ CreateDrawable(Display *dpy, struct glx_config *config,
>    UnlockDisplay(dpy);
>    SyncHandle();
> 
> +   if (InitGLXDrawable(dpy, glxDraw, drawable, req->glxwindow)) {
> +      free(glxDraw);
> +      return None;
> +   }
> +
>    CreateDRIDrawable(dpy, config, drawable, req->glxwindow, attrib_list, i);
> 
>    return req->glxwindow;
> @@ -425,7 +436,9 @@ CreateDrawable(Display *dpy, struct glx_config *config,
> static void
> DestroyDrawable(Display * dpy, GLXDrawable drawable, CARD32 glxCode)
> {
> +   struct glx_display *const priv = __glXInitialize(dpy);
>    xGLXDestroyPbufferReq *req;
> +   struct glx_drawable *glxDraw;
>    CARD8 opcode;
> 
>    if ((dpy == NULL) || (drawable == 0)) {
> @@ -447,6 +460,7 @@ DestroyDrawable(Display * dpy, GLXDrawable drawable, CARD32 glxCode)
>    UnlockDisplay(dpy);
>    SyncHandle();
> 
> +   DestroyGLXDrawable(dpy, drawable);
>    DestroyDRIDrawable(dpy, drawable, GL_FALSE);
> 
>    return;
> diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h
> index 2b6966f..f6aeeef 100644
> --- a/src/glx/glxclient.h
> +++ b/src/glx/glxclient.h
> @@ -570,6 +570,8 @@ struct glx_display
>      */
>    struct glx_screen **screens;
> 
> +   __glxHashTable *glXDrawHash;
> +
> #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
>    __glxHashTable *drawHash;
> 
> @@ -582,6 +584,14 @@ struct glx_display
> #endif
> };
> 
> +struct glx_drawable {
> +   XID xDrawable;
> +   XID drawable;
> +
> +   uint32_t lastEventSbc;
> +   int64_t eventSbcWrap;
> +};
> +
> extern int
> glx_screen_init(struct glx_screen *psc,
> 		int screen, struct glx_display * priv);
> @@ -775,6 +785,12 @@ GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable);
> 
> #endif
> 
> +
> +extern struct glx_drawable *GetGLXDrawable(Display *dpy, GLXDrawable drawable);
> +extern int InitGLXDrawable(Display *dpy, struct glx_drawable *glxDraw,
> +			   XID xDrawable, GLXDrawable drawable);
> +extern void DestroyGLXDrawable(Display *dpy, GLXDrawable drawable);
> +
> extern struct glx_context dummyContext;
> 
> extern struct glx_screen *
> diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c
> index 22bebab..55e53f4 100644
> --- a/src/glx/glxcmds.c
> +++ b/src/glx/glxcmds.c
> @@ -90,6 +90,51 @@ GetGLXDRIDrawable(Display * dpy, GLXDrawable drawable)
> 
> #endif
> 
> +_X_HIDDEN struct glx_drawable *
> +GetGLXDrawable(Display *dpy, GLXDrawable drawable)
> +{
> +   struct glx_display *priv = __glXInitialize(dpy);
> +   struct glx_drawable *glxDraw;
> +
> +   if (priv == NULL)
> +      return NULL;
> +
> +   if (__glxHashLookup(priv->glXDrawHash, drawable, (void *) &glxDraw) == 0)
> +      return glxDraw;
> +
> +   return NULL;
> +}
> +
> +_X_HIDDEN int
> +InitGLXDrawable(Display *dpy, struct glx_drawable *glxDraw, XID xDrawable,
> +		GLXDrawable drawable)
> +{
> +   struct glx_display *priv = __glXInitialize(dpy);
> +
> +   if (!priv)
> +      return -1;
> +
> +   glxDraw->xDrawable = xDrawable;
> +   glxDraw->drawable = drawable;
> +   glxDraw->lastEventSbc = 0;
> +   glxDraw->eventSbcWrap = 0;
> +
> +   return __glxHashInsert(priv->glXDrawHash, drawable, glxDraw);
> +}
> +
> +_X_HIDDEN void
> +DestroyGLXDrawable(Display *dpy, GLXDrawable drawable)
> +{
> +   struct glx_display *priv = __glXInitialize(dpy);
> +   struct glx_drawable *glxDraw;
> +
> +   if (!priv)
> +      return;
> +
> +   glxDraw = GetGLXDrawable(dpy, drawable);
> +   __glxHashDelete(priv->glXDrawHash, drawable);
> +   free(glxDraw);
> +}
> 
> /**
>  * Get the GLX per-screen data structure associated with a GLX context.
> @@ -615,6 +660,7 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap)
>    return pixmap;
> #else
>    xGLXCreateGLXPixmapReq *req;
> +   struct glx_drawable *glxDraw;
>    GLXPixmap xid;
>    CARD8 opcode;
> 
> @@ -623,6 +669,10 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap)
>       return None;
>    }
> 
> +   glxDraw = Xmalloc(sizeof(*glxDraw));
> +   if (!glxDraw)
> +      return None;
> +
>    /* Send the glXCreateGLXPixmap request */
>    LockDisplay(dpy);
>    GetReq(GLXCreateGLXPixmap, req);
> @@ -635,6 +685,11 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap)
>    UnlockDisplay(dpy);
>    SyncHandle();
> 
> +   if (InitGLXDrawable(dpy, glxDraw, pixmap, req->glxpixmap)) {
> +      free(glxDraw);
> +      return None;
> +   }
> +
> #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
>    do {
>       /* FIXME: Maybe delay __DRIdrawable creation until the drawable
> @@ -693,6 +748,8 @@ glXDestroyGLXPixmap(Display * dpy, GLXPixmap glxpixmap)
>    UnlockDisplay(dpy);
>    SyncHandle();
> 
> +   DestroyGLXDrawable(dpy, glxpixmap);
> +
> #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
>    {
>       struct glx_display *const priv = __glXInitialize(dpy);
> diff --git a/src/glx/glxext.c b/src/glx/glxext.c
> index 02652cb..03c05a3 100644
> --- a/src/glx/glxext.c
> +++ b/src/glx/glxext.c
> @@ -106,7 +106,7 @@ XEXT_GENERATE_ERROR_STRING(__glXErrorString, __glXExtensionName,
> static Bool
> __glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
> {
> -     struct glx_display *glx_dpy = __glXInitialize(dpy);
> +   struct glx_display *glx_dpy = __glXInitialize(dpy);
> 
>    if (glx_dpy == NULL)
>       return False;
> @@ -134,11 +134,19 @@ __glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
>    {
>       GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
>       xGLXBufferSwapComplete2 *awire = (xGLXBufferSwapComplete2 *)wire;
> +      struct glx_drawable *glxDraw = GetGLXDrawable(dpy, awire->drawable);
>       aevent->event_type = awire->event_type;
>       aevent->drawable = awire->drawable;
>       aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo;
>       aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo;
> -      aevent->sbc = awire->sbc;
> +
> +      if (!glxDraw)
> +	 return False;
> +
> +      if (awire->sbc < glxDraw->lastEventSbc)
> +	 glxDraw->eventSbcWrap += 0x100000000;
> +      glxDraw->lastEventSbc = awire->sbc;
> +      aevent->sbc = awire->sbc + glxDraw->eventSbcWrap;
>       return True;
>    }
>    default:
> @@ -227,6 +235,8 @@ glx_display_free(struct glx_display *priv)
>    if (priv->serverGLXversion)
>       Xfree((char *) priv->serverGLXversion);
> 
> +   __glxHashDestroy(priv->glXDrawHash);
> +
> #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
>    __glxHashDestroy(priv->drawHash);
> 
> @@ -846,6 +856,8 @@ __glXInitialize(Display * dpy)
>    XESetCloseDisplay(dpy, dpyPriv->codes->extension, __glXCloseDisplay);
>    XESetErrorString (dpy, dpyPriv->codes->extension,__glXErrorString);
> 
> +   dpyPriv->glXDrawHash = __glxHashCreate();
> +
> #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
>    glx_direct = (getenv("LIBGL_ALWAYS_INDIRECT") == NULL);
>    glx_accel = (getenv("LIBGL_ALWAYS_SOFTWARE") == NULL);
> -- 
> 1.7.4.1
> 
> 



More information about the xorg-devel mailing list