[PATCH] DRI2/GLX: fix swap event handling

Jesse Barnes jbarnes at virtuousgeek.org
Thu Apr 28 13:27:22 PDT 2011


Use the new swap event structure packing and send it to the client if
possible.  This means tracking client version information when clients
connect.  If they don't support the new packing, they'll get the old
bits and fill junk into their sbc values when they receive the event.
If they do support the new packing, send off the right data.
---
 configure.ac                |    4 +-
 glx/glxdri2.c               |   28 +++++++++++++++++++-
 hw/xfree86/dri2/dri2.c      |   57 ++++++++++++++++++++++++++++++++++++++++++-
 hw/xfree86/dri2/dri2ext.c   |   14 ++++++++++-
 include/protocol-versions.h |    2 +-
 5 files changed, 98 insertions(+), 7 deletions(-)

diff --git a/configure.ac b/configure.ac
index 6eb780c..87194a5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -771,11 +771,11 @@ RECORDPROTO="recordproto >= 1.13.99.1"
 SCRNSAVERPROTO="scrnsaverproto >= 1.1"
 RESOURCEPROTO="resourceproto"
 DRIPROTO="xf86driproto >= 2.1.0"
-DRI2PROTO="dri2proto >= 2.3"
+DRI2PROTO="dri2proto >= 2.4"
 XINERAMAPROTO="xineramaproto"
 BIGFONTPROTO="xf86bigfontproto >= 1.2.0"
 DGAPROTO="xf86dgaproto >= 2.0.99.1"
-GLPROTO="glproto >= 1.4.10"
+GLPROTO="glproto >= 1.4.13"
 DMXPROTO="dmxproto >= 2.2.99.1"
 VIDMODEPROTO="xf86vidmodeproto >= 2.2.99.1"
 WINDOWSWMPROTO="windowswmproto"
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index d979717..654b4ae 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -192,8 +192,17 @@ __glXdriSwapEvent(ClientPtr client, void *data, int type, CARD64 ust,
     wire.ust_lo = ust & 0xffffffff;
     wire.msc_hi = msc >> 32;
     wire.msc_lo = msc & 0xffffffff;
-    wire.sbc_hi = sbc >> 32;
-    wire.sbc_lo = sbc & 0xffffffff;
+    wire.sbc_hi = 0;
+
+    if (DRI2ClientSupportsSBC(client)) {
+	wire.sbc_lo0 = sbc & 0xff;
+	wire.sbc_lo8 = (sbc >> 8) & 0xff;
+	wire.sbc_lo16 = (sbc >> 16) & 0xff;
+    } else {
+	wire.sbc_lo0 = 0;
+	wire.sbc_lo8 = 0;
+	wire.sbc_lo16 = 0;
+    }
 
     WriteEventsToClient(client, 1, (xEvent *) &wire);
 }
@@ -228,6 +237,18 @@ __glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable *drawable)
     return TRUE;
 }
 
+static void
+__glXDRIclientGone(CallbackListPtr	*list,
+		   pointer		closure,
+		   pointer		data)
+{
+    NewClientInfoRec	*clientinfo = (NewClientInfoRec *) data;
+    ClientPtr		pClient = clientinfo->client;
+
+    if (pClient->clientState == ClientStateGone)
+	DRI2ClientGone(client);
+}
+
 static int
 __glXDRIdrawableSwapInterval(__GLXdrawable *drawable, int interval)
 {
@@ -769,6 +790,9 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
     screen->leaveVT = pScrn->LeaveVT;
     pScrn->LeaveVT = glxDRILeaveVT;
 
+    if (!AddCallback (&ClientStateCallback, __glXDRIclientGone, 0))
+	return;
+
     LogMessage(X_INFO,
 	       "AIGLX: Loaded and initialized %s\n", driverName);
 
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 5c42a51..9b5eab2 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -60,6 +60,9 @@ static DevPrivateKeyRec dri2WindowPrivateKeyRec;
 static DevPrivateKeyRec dri2PixmapPrivateKeyRec;
 #define dri2PixmapPrivateKey (&dri2PixmapPrivateKeyRec)
 
+static DevPrivateKeyRec dri2ClientPrivateKeyRec;
+#define dri2ClientPrivateKey (&dri2ClientPrivateKeyRec)
+
 static RESTYPE       dri2DrawableRes;
 
 typedef struct _DRI2Screen *DRI2ScreenPtr;
@@ -107,6 +110,11 @@ typedef struct _DRI2Screen {
     ConfigNotifyProcPtr		 ConfigNotify;
 } DRI2ScreenRec;
 
+typedef struct _DRI2Client {
+    CARD32 major;
+    CARD32 minor;
+} DRI2ClientRec, *DRI2ClientPtr;
+
 static DRI2ScreenPtr
 DRI2GetScreen(ScreenPtr pScreen)
 {
@@ -131,6 +139,12 @@ DRI2GetDrawable(DrawablePtr pDraw)
     }
 }
 
+static DRI2ClientPtr
+DRI2GetClient(ClientPtr client)
+{
+    return dixLookupPrivate(&client->devPrivates, dri2ClientPrivateKey);
+}
+
 static unsigned long
 DRI2DrawableSerial(DrawablePtr pDraw)
 {
@@ -190,6 +204,44 @@ DRI2AllocateDrawable(DrawablePtr pDraw)
     return pPriv;
 }
 
+void
+DRI2InitClient(ClientPtr client, CARD32 major, CARD32 minor)
+{
+    DRI2ClientPtr pPriv;
+
+    pPriv = malloc(sizeof *pPriv);
+    if (!pPriv)
+	return;
+
+    pPriv->major = major;
+    pPriv->minor = minor;
+
+    dixSetPrivate(&client->devPrivates, dri2ClientPrivateKey, pPriv);
+}
+
+void
+DRI2ClientGone(ClientPtr client)
+{
+    DRI2ClientPtr pPriv = DRI2GetClient(client);
+
+    if (pPriv)
+	free(pPriv);
+}
+
+Bool
+DRI2ClientSupportsSBC(ClientPtr client)
+{
+    DRI2ClientPtr pPriv = DRI2GetClient(client);
+
+    if (!pPriv)
+	return FALSE;
+
+    if (pPriv->major > 1 || (pPriv->major == 1 && pPriv->minor > 3))
+	return TRUE;
+
+    return FALSE;
+}
+
 typedef struct DRI2DrawableRefRec {
     XID		  id;
     XID		  dri2_id;
@@ -1097,6 +1149,9 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
     if (!dixRegisterPrivateKey(&dri2PixmapPrivateKeyRec, PRIVATE_PIXMAP, 0))
 	return FALSE;
 
+    if (!dixRegisterPrivateKey(&dri2ClientPrivateKeyRec, PRIVATE_CLIENT, 0))
+	return FALSE;
+
     ds = calloc(1, sizeof *ds);
     if (!ds)
 	return FALSE;
@@ -1114,7 +1169,7 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
 	ds->ScheduleSwap = info->ScheduleSwap;
 	ds->ScheduleWaitMSC = info->ScheduleWaitMSC;
 	ds->GetMSC = info->GetMSC;
-	cur_minor = 3;
+	cur_minor = 4;
     } else {
 	cur_minor = 1;
     }
diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
index 4e48e65..b634bf9 100644
--- a/hw/xfree86/dri2/dri2ext.c
+++ b/hw/xfree86/dri2/dri2ext.c
@@ -77,6 +77,9 @@ ProcDRI2QueryVersion(ClientPtr client)
 	swaps(&stuff->length, n);
 
     REQUEST_SIZE_MATCH(xDRI2QueryVersionReq);
+
+    DRI2InitClient(client, stuff->majorVersion, stuff->minorVersion);
+
     rep.type = X_Reply;
     rep.length = 0;
     rep.sequenceNumber = client->sequence;
@@ -370,7 +373,16 @@ DRI2SwapEvent(ClientPtr client, void *data, int type, CARD64 ust, CARD64 msc,
     event.msc_hi = (CARD64)msc >> 32;
     event.msc_lo = msc & 0xffffffff;
     event.sbc_hi = (CARD64)sbc >> 32;
-    event.sbc_lo = sbc & 0xffffffff;
+
+    if (DRI2ClientSupportsSBC(client)) {
+	event.sbc_lo0 = sbc & 0xff;
+	event.sbc_lo8 = (sbc >> 8) & 0xff;
+	event.sbc_lo16 = (sbc >> 16) & 0xffff;
+    } else {
+	event.sbc_lo0 = 0;
+	event.sbc_lo8 = 0;
+	event.sbc_lo16 = 0;
+    }
 
     WriteEventsToClient(client, 1, (xEvent *)&event);
 }
diff --git a/include/protocol-versions.h b/include/protocol-versions.h
index 8692ded..8fde917 100644
--- a/include/protocol-versions.h
+++ b/include/protocol-versions.h
@@ -57,7 +57,7 @@
 
 /* GLX */
 #define SERVER_GLX_MAJOR_VERSION		1
-#define SERVER_GLX_MINOR_VERSION		4
+#define SERVER_GLX_MINOR_VERSION		5
 
 /* Xinerama */
 #define SERVER_PANORAMIX_MAJOR_VERSION          1
-- 
1.7.1



More information about the xorg-devel mailing list