diff --git a/configure.ac b/configure.ac index 1b20fc6b2..029c9b488 100644 --- a/configure.ac +++ b/configure.ac @@ -755,7 +755,7 @@ XINERAMAPROTO="xineramaproto" BIGFONTPROTO="xf86bigfontproto >= 1.2.0" XCALIBRATEPROTO="xcalibrateproto" DGAPROTO="xf86dgaproto >= 2.0.99.1" -GLPROTO="glproto >= 1.4.9" +GLPROTO="glproto >= 1.4.10" DMXPROTO="dmxproto >= 2.2.99.1" VIDMODEPROTO="xf86vidmodeproto >= 2.2.99.1" WINDOWSWMPROTO="windowswmproto" diff --git a/glx/extension_string.c b/glx/extension_string.c index 9d110cf98..7721cb056 100644 --- a/glx/extension_string.c +++ b/glx/extension_string.c @@ -82,6 +82,7 @@ static const struct extension_info known_glx_extensions[] = { { GLX(SGIX_fbconfig), VER(1,3), Y, }, { GLX(SGIX_pbuffer), VER(1,3), Y, }, { GLX(SGIX_visual_select_group), VER(0,0), Y, }, + { GLX(INTEL_swap_event), VER(1,4), N, }, { NULL } }; diff --git a/glx/extension_string.h b/glx/extension_string.h index 98e91bc18..912534a04 100644 --- a/glx/extension_string.h +++ b/glx/extension_string.h @@ -50,6 +50,7 @@ enum { SGIX_fbconfig_bit, SGIX_pbuffer_bit, SGIX_visual_select_group_bit, + INTEL_swap_event_bit, __NUM_GLX_EXTS, }; diff --git a/glx/glxdri2.c b/glx/glxdri2.c index 58e4684fe..69fd39b3b 100644 --- a/glx/glxdri2.c +++ b/glx/glxdri2.c @@ -167,6 +167,43 @@ __glXDRIdrawableWaitGL(__GLXdrawable *drawable) DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft); } +static void +__glXdriSwapEvent(ClientPtr client, void *data, int type, CARD64 ust, + CARD64 msc, CARD64 sbc) +{ + __GLXdrawable *drawable = data; + xGLXBufferSwapComplete wire; + + if (!drawable->eventMask & GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK) + return; + + wire.type = __glXEventBase + GLX_BufferSwapComplete; + switch (type) { + case DRI2_EXCHANGE_COMPLETE: + wire.event_type = GLX_EXCHANGE_COMPLETE_INTEL; + break; + case DRI2_BLIT_COMPLETE: + wire.event_type = GLX_BLIT_COMPLETE_INTEL; + break; + case DRI2_FLIP_COMPLETE: + wire.event_type = GLX_FLIP_COMPLETE_INTEL; + break; + default: + /* unknown swap completion type */ + break; + } + wire.sequenceNumber = client->sequence; + wire.drawable = drawable->drawId; + wire.ust_hi = ust >> 32; + 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; + + WriteEventsToClient(client, 1, (xEvent *) &wire); +} + /* * Copy or flip back to front, honoring the swap interval if possible. * @@ -184,7 +221,7 @@ __glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable *drawable) (*screen->flush->flushInvalidate)(priv->driDrawable); if (DRI2SwapBuffers(client, drawable->pDraw, 0, 0, 0, &unused, - NULL, drawable->pDraw) != Success) + __glXdriSwapEvent, drawable->pDraw) != Success) return FALSE; return TRUE; @@ -581,6 +618,10 @@ initializeExtensions(__GLXDRIscreen *screen) "GLX_MESA_copy_sub_buffer"); LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n"); + /* FIXME: only if DDX supports it */ + __glXEnableExtension(screen->glx_enable_bits, "GLX_INTEL_swap_event"); + LogMessage(X_INFO, "AIGLX: enabled GLX_INTEL_swap_event\n"); + for (i = 0; extensions[i]; i++) { #ifdef __DRI_READ_DRAWABLE if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) { diff --git a/glx/glxext.c b/glx/glxext.c index 913c624f2..59bcfbed2 100644 --- a/glx/glxext.c +++ b/glx/glxext.c @@ -267,6 +267,7 @@ GLboolean __glXErrorOccured(void) } static int __glXErrorBase; +int __glXEventBase; int __glXError(int error) { @@ -403,6 +404,7 @@ void GlxExtensionInit(void) } __glXErrorBase = extEntry->errorBase; + __glXEventBase = extEntry->eventBase; } /************************************************************************/ diff --git a/glx/glxscreens.c b/glx/glxscreens.c index 674e2c681..58d8ee0b4 100644 --- a/glx/glxscreens.c +++ b/glx/glxscreens.c @@ -181,6 +181,7 @@ static char GLXServerExtensions[] = "GLX_SGIX_fbconfig " "GLX_SGIX_pbuffer " "GLX_MESA_copy_sub_buffer " + "GLX_INTEL_swap_event" ; /* diff --git a/glx/glxserver.h b/glx/glxserver.h index 10c4889e1..1daf97758 100644 --- a/glx/glxserver.h +++ b/glx/glxserver.h @@ -249,4 +249,6 @@ extern int __glXImageSize(GLenum format, GLenum type, extern unsigned glxMajorVersion; extern unsigned glxMinorVersion; +extern int __glXEventBase; + #endif /* !__GLX_server_h__ */ diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h index be14b9d2e..dd59297df 100644 --- a/hw/xfree86/dri2/dri2.h +++ b/hw/xfree86/dri2/dri2.h @@ -169,6 +169,8 @@ typedef struct { DRI2ScheduleWaitMSCProcPtr ScheduleWaitMSC; } DRI2InfoRec, *DRI2InfoPtr; +extern _X_EXPORT int DRI2EventBase; + extern _X_EXPORT Bool DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info); diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c index fb8f9089d..3e6b03e4e 100644 --- a/hw/xfree86/dri2/dri2ext.c +++ b/hw/xfree86/dri2/dri2ext.c @@ -348,6 +348,25 @@ vals_to_card64(CARD32 lo, CARD32 hi) return (CARD64)hi << 32 | lo; } +static void +DRI2SwapEvent(ClientPtr client, void *data, int type, CARD64 ust, CARD64 msc, + CARD64 sbc) +{ + xDRI2BufferSwapComplete event; + + event.type = DRI2EventBase + DRI2_BufferSwapComplete; + event.sequenceNumber = client->sequence; + event.event_type = type; + 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); +} + static int ProcDRI2SwapBuffers(ClientPtr client) { @@ -368,7 +387,7 @@ ProcDRI2SwapBuffers(ClientPtr client) remainder = vals_to_card64(stuff->remainder_lo, stuff->remainder_hi); status = DRI2SwapBuffers(client, pDrawable, target_msc, divisor, remainder, - &swap_target, NULL, pDrawable); + &swap_target, DRI2SwapEvent, pDrawable); if (status != Success) return BadDrawable; @@ -608,6 +627,8 @@ static int DRI2DrawableGone(pointer p, XID id) return Success; } +int DRI2EventBase; + static void DRI2ExtensionInit(void) { @@ -624,6 +645,7 @@ DRI2ExtensionInit(void) NULL, StandardMinorOpcode); + DRI2EventBase = dri2Extension->eventBase; } extern Bool noDRI2Extension;