[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