[PATCH 7/8] DRI2: support generic swap events

Jesse Barnes jbarnes at virtuousgeek.org
Tue May 3 10:59:20 PDT 2011


Send the new generic swap event type if the client supports it.  This
means checking the client's DRI2 proto version at connect time and then
constructing a new generic event at swap complete time.  To track the
client version, we need to add a new DRI2 client private type and track
it for the lifetime of the client.

Signed-off-by: Jesse Barnes <jbarnes at virtuousgeek.org>
---
 configure.ac              |    2 +-
 glx/glxdri2.c             |   20 +++++++++++++++
 hw/xfree86/dri2/dri2.c    |   57 ++++++++++++++++++++++++++++++++++++++++++++-
 hw/xfree86/dri2/dri2.h    |    6 ++++
 hw/xfree86/dri2/dri2ext.c |   47 +++++++++++++++++++++++++++---------
 5 files changed, 118 insertions(+), 14 deletions(-)

diff --git a/configure.ac b/configure.ac
index 6eb780c..8e00fe7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -771,7 +771,7 @@ 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"
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 93c5e5b..a17b4d5 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -228,6 +228,23 @@ __glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable *drawable)
     return TRUE;
 }
 
+static void
+__glXDRIclientCallback(CallbackListPtr	*list,
+		   pointer		closure,
+		   pointer		data)
+{
+    NewClientInfoRec	*clientinfo = (NewClientInfoRec *) data;
+    ClientPtr		pClient = clientinfo->client;
+
+    switch (pClient->clientState) {
+    case ClientStateGone:
+	DRI2ClientGone(pClient);
+	break;
+    default:
+	break;
+    }
+}
+
 static int
 __glXDRIdrawableSwapInterval(__GLXdrawable *drawable, int interval)
 {
@@ -769,6 +786,9 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
     screen->leaveVT = pScrn->LeaveVT;
     pScrn->LeaveVT = glxDRILeaveVT;
 
+    if (!AddCallback (&ClientStateCallback, __glXDRIclientCallback, 0))
+	return NULL;
+
     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/dri2.h b/hw/xfree86/dri2/dri2.h
index fe0bf6c..97e8e86 100644
--- a/hw/xfree86/dri2/dri2.h
+++ b/hw/xfree86/dri2/dri2.h
@@ -192,6 +192,7 @@ typedef struct {
 }  DRI2InfoRec, *DRI2InfoPtr;
 
 extern _X_EXPORT int DRI2EventBase;
+extern _X_EXPORT int DRI2ExtCode;
 
 extern _X_EXPORT Bool DRI2ScreenInit(ScreenPtr	pScreen,
 		    DRI2InfoPtr info);
@@ -283,5 +284,10 @@ extern _X_EXPORT void DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw,
 extern _X_EXPORT void DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw,
 					  int frame, unsigned int tv_sec,
 					  unsigned int tv_usec);
+extern _X_EXPORT Bool DRI2ClientSupportsSBC(ClientPtr client);
+extern _X_EXPORT void DRI2ClientGone(ClientPtr client);
+extern _X_EXPORT void DRI2InitClient(ClientPtr client, CARD32 major,
+				     CARD32 minor);
+
 
 #endif
diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
index 4e48e65..2dd65fb 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;
@@ -359,20 +362,38 @@ static void
 DRI2SwapEvent(ClientPtr client, void *data, int type, CARD64 ust, CARD64 msc,
 	      CARD64 sbc)
 {
-    xDRI2BufferSwapComplete event;
     DrawablePtr pDrawable = data;
 
-    event.type = DRI2EventBase + DRI2_BufferSwapComplete;
-    event.event_type = type;
-    event.drawable = pDrawable->id;
-    event.ust_hi = (CARD64)ust >> 32;
-    event.ust_lo = ust & 0xffffffff;
-    event.msc_hi = (CARD64)msc >> 32;
-    event.msc_lo = msc & 0xffffffff;
-    event.sbc_hi = (CARD64)sbc >> 32;
-    event.sbc_lo = sbc & 0xffffffff;
-
-    WriteEventsToClient(client, 1, (xEvent *)&event);
+    if (DRI2ClientSupportsSBC(client)) {
+	xDRI2BufferSwapComplete2 event;
+
+	event.type = GenericEvent;
+	event.extension = DRI2ExtCode;
+	event.evtype = DRI2_BufferSwapComplete;
+	event.swap_event_type = type;
+	event.drawable = pDrawable->id;
+	event.length = 8;
+	event.ust_hi = (CARD64)ust >> 32;
+	event.ust_lo = ust & 0xffffffff;
+	event.msc_hi = (CARD64)msc >> 32;
+	event.msc_lo = msc & 0xffffffff;
+	event.sbc_hi = (CARD64)sbc >> 32;
+	event.sbc_lo = sbc & 0xffffffff;
+	WriteEventsToClient(client, 1, (xEvent *)&event);
+    } else {
+	xDRI2BufferSwapComplete event;
+
+	event.type = DRI2EventBase + DRI2_BufferSwapComplete;
+	event.event_type = type;
+	event.drawable = pDrawable->id;
+	event.ust_hi = (CARD64)ust >> 32;
+	event.ust_lo = ust & 0xffffffff;
+	event.msc_hi = (CARD64)msc >> 32;
+	event.msc_lo = msc & 0xffffffff;
+	event.sbc_hi = 0;
+	event.sbc_lo = 0;
+	WriteEventsToClient(client, 1, (xEvent *)&event);
+    }
 }
 
 static int
@@ -624,6 +645,7 @@ SProcDRI2Dispatch (ClientPtr client)
 }
 
 int DRI2EventBase;
+int DRI2ExtCode;
 
 static void
 DRI2ExtensionInit(void)
@@ -637,6 +659,7 @@ DRI2ExtensionInit(void)
 				 StandardMinorOpcode);
 
     DRI2EventBase = dri2Extension->eventBase;
+    DRI2ExtCode = dri2Extension->base;
 }
 
 extern Bool noDRI2Extension;
-- 
1.7.4.1



More information about the xorg-devel mailing list