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@xxxxxxxxxxxxxxxx> --- 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 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel