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

Jesse Barnes jbarnes at virtuousgeek.org
Fri May 6 14:01:00 PDT 2011


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 mesa-dev mailing list