From 3dd5bfe540b295bb37a2c2fd0ba4a31fb217612b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 21 Nov 2013 22:48:31 -0800 Subject: [PATCH] present: Send GLX_BufferSwapComplete events from present extension This allows GL to support the GLX_INTEL_swap_event extension. v2: Return GLX_BLIT_COMPLETE_INTEL for unknown swap types Signed-off-by: Keith Packard Reviewed-by: Adam Jackson --- glx/Makefile.am | 3 ++- glx/glxcmds.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++ glx/glxdri2.c | 33 +++++++++----------------- glx/glxext.c | 3 +++ glx/glxserver.h | 9 ++++++++ present/present.h | 9 ++++++++ present/present_event.c | 10 ++++++++ 7 files changed, 105 insertions(+), 23 deletions(-) diff --git a/glx/Makefile.am b/glx/Makefile.am index 5f28e87..44d3a7d 100644 --- a/glx/Makefile.am +++ b/glx/Makefile.am @@ -20,7 +20,8 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/hw/xfree86/os-support/bus \ -I$(top_srcdir)/hw/xfree86/common \ -I$(top_srcdir)/hw/xfree86/dri \ - -I$(top_srcdir)/mi + -I$(top_srcdir)/mi \ + -I$(top_srcdir)/present if DRI2_AIGLX AM_CPPFLAGS += -I$(top_srcdir)/hw/xfree86/dri2 diff --git a/glx/glxcmds.c b/glx/glxcmds.c index efa4aec..b8da048 100644 --- a/glx/glxcmds.c +++ b/glx/glxcmds.c @@ -2468,3 +2468,64 @@ __glXDisp_ClientInfo(__GLXclientState * cl, GLbyte * pc) return Success; } + +#include + +void +__glXsendSwapEvent(__GLXdrawable *drawable, int type, CARD64 ust, + CARD64 msc, CARD32 sbc) +{ + ClientPtr client = clients[CLIENT_ID(drawable->drawId)]; + + xGLXBufferSwapComplete2 wire = { + .type = __glXEventBase + GLX_BufferSwapComplete + }; + + if (!client) + return; + + if (!(drawable->eventMask & GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK)) + return; + + wire.event_type = type; + 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 = sbc; + + WriteEventsToClient(client, 1, (xEvent *) &wire); +} + +#if PRESENT +static void +__glXpresentCompleteNotify(WindowPtr window, CARD8 present_mode, CARD32 serial, + uint64_t ust, uint64_t msc) +{ + __GLXdrawable *drawable; + int glx_type; + int rc; + + rc = dixLookupResourceByType((pointer *) &drawable, window->drawable.id, + __glXDrawableRes, serverClient, DixGetAttrAccess); + + if (rc != Success) + return; + + if (present_mode == PresentCompleteModeFlip) + glx_type = GLX_FLIP_COMPLETE_INTEL; + else + glx_type = GLX_BLIT_COMPLETE_INTEL; + + __glXsendSwapEvent(drawable, glx_type, ust, msc, serial); +} + +#include + +void +__glXregisterPresentCompleteNotify(void) +{ + present_register_complete_notify(__glXpresentCompleteNotify); +} +#endif diff --git a/glx/glxdri2.c b/glx/glxdri2.c index fbbd1fd..e245e81 100644 --- a/glx/glxdri2.c +++ b/glx/glxdri2.c @@ -177,36 +177,25 @@ __glXdriSwapEvent(ClientPtr client, void *data, int type, CARD64 ust, CARD64 msc, CARD32 sbc) { __GLXdrawable *drawable = data; - xGLXBufferSwapComplete2 wire = { - .type = __glXEventBase + GLX_BufferSwapComplete - }; - - if (!(drawable->eventMask & GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK)) - return; - + int glx_type; switch (type) { case DRI2_EXCHANGE_COMPLETE: - wire.event_type = GLX_EXCHANGE_COMPLETE_INTEL; + glx_type = GLX_EXCHANGE_COMPLETE_INTEL; break; + default: + /* unknown swap completion type, + * BLIT is a reasonable default, so + * fall through ... + */ case DRI2_BLIT_COMPLETE: - wire.event_type = GLX_BLIT_COMPLETE_INTEL; + glx_type = GLX_BLIT_COMPLETE_INTEL; break; case DRI2_FLIP_COMPLETE: - wire.event_type = GLX_FLIP_COMPLETE_INTEL; - break; - default: - /* unknown swap completion type */ - wire.event_type = 0; + glx_type = GLX_FLIP_COMPLETE_INTEL; break; } - 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 = sbc; - - WriteEventsToClient(client, 1, (xEvent *) &wire); + + __glXsendSwapEvent(drawable, glx_type, ust, msc, sbc); } /* diff --git a/glx/glxext.c b/glx/glxext.c index 3a7de28..601d08a 100644 --- a/glx/glxext.c +++ b/glx/glxext.c @@ -399,6 +399,9 @@ GlxExtensionInit(void) __glXErrorBase = extEntry->errorBase; __glXEventBase = extEntry->eventBase; +#if PRESENT + __glXregisterPresentCompleteNotify(); +#endif } /************************************************************************/ diff --git a/glx/glxserver.h b/glx/glxserver.h index 5e29abb..f862b63 100644 --- a/glx/glxserver.h +++ b/glx/glxserver.h @@ -120,6 +120,15 @@ void glxResumeClients(void); void __glXsetGetProcAddress(void (*(*get_proc_address) (const char *)) (void)); void *__glGetProcAddress(const char *); +void +__glXsendSwapEvent(__GLXdrawable *drawable, int type, CARD64 ust, + CARD64 msc, CARD32 sbc); + +#if PRESENT +void +__glXregisterPresentCompleteNotify(void); +#endif + /* ** State kept per client. */ diff --git a/present/present.h b/present/present.h index 6a451fb..0e3bdc0 100644 --- a/present/present.h +++ b/present/present.h @@ -115,4 +115,13 @@ present_event_abandon(RRCrtcPtr crtc); extern _X_EXPORT Bool present_screen_init(ScreenPtr screen, present_screen_info_ptr info); +typedef void (*present_complete_notify_proc)(WindowPtr window, + CARD8 mode, + CARD32 serial, + uint64_t ust, + uint64_t msc); + +extern _X_EXPORT void +present_register_complete_notify(present_complete_notify_proc proc); + #endif /* _PRESENT_H_ */ diff --git a/present/present_event.c b/present/present_event.c index a8f7176..f0d509e 100644 --- a/present/present_event.c +++ b/present/present_event.c @@ -137,6 +137,14 @@ present_send_config_notify(WindowPtr window, int x, int y, int w, int h, int bw, } } +static present_complete_notify_proc complete_notify; + +void +present_register_complete_notify(present_complete_notify_proc proc) +{ + complete_notify = proc; +} + void present_send_complete_notify(WindowPtr window, CARD8 kind, CARD8 mode, CARD32 serial, uint64_t ust, uint64_t msc) { @@ -165,6 +173,8 @@ present_send_complete_notify(WindowPtr window, CARD8 kind, CARD8 mode, CARD32 se } } } + if (complete_notify) + (*complete_notify)(window, mode, serial, ust, msc); } void -- 2.7.4