diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-08-21 21:03:04 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-08-21 22:20:02 +0100 |
commit | 5c77b4df146796d8280a4f5b16949e3db4a1f84a (patch) | |
tree | 8216d8c03138ed46938f896903fa9476dbb84856 /src/cairo-xlib-surface-shm.c | |
parent | aa5c7123097c56e2c35bf88b8377bbdd1523fbce (diff) | |
download | cairo-5c77b4df146796d8280a4f5b16949e3db4a1f84a.tar.gz |
xlib/shm: Only check if we are expecting an event
As the XCheckWindowEvent() has the unwanted side-effect of flushing the
output queue when there is no event available (libX11 seems to be
entirely anti-performant), we need to roll our own that only checks the
already available event queue.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/cairo-xlib-surface-shm.c')
-rw-r--r-- | src/cairo-xlib-surface-shm.c | 62 |
1 files changed, 46 insertions, 16 deletions
diff --git a/src/cairo-xlib-surface-shm.c b/src/cairo-xlib-surface-shm.c index d10e8a6d0..25e6a871f 100644 --- a/src/cairo-xlib-surface-shm.c +++ b/src/cairo-xlib-surface-shm.c @@ -105,6 +105,9 @@ struct _cairo_xlib_shm_display { int has_pixmaps; Window window; + unsigned pending_events; + unsigned last_event; + cairo_list_t pool; struct pqueue info; }; @@ -298,20 +301,61 @@ peek_processed (cairo_device_t *device) return LastKnownRequestProcessed (peek_display(device)); } +static void +flush_events (cairo_xlib_display_t *display) +{ + cairo_xlib_shm_display_t *shm; + Display *dpy; + _XQEvent *prev, *qelt, *next; + + shm = display->shm; + if (shm == NULL) + return; + + if (shm->pending_events == 0) + return; + + dpy = display->display; + if (QLength (dpy) == 0) + return; + + LockDisplay(dpy); + for (prev = NULL, qelt = dpy->head; qelt; qelt = next) { + next = qelt->next; + if (qelt->event.xany.window == shm->window) { + _XDeq(dpy, prev, qelt); + if (! --shm->pending_events) + break; + + continue; + } + prev = qelt; + } + UnlockDisplay(dpy); + + /* Did somebody else eat all of our events? */ + if (seqno_passed (shm->last_event, LastKnownRequestProcessed (dpy))) + shm->pending_events = 0; +} + static void trigger_event (cairo_xlib_display_t *display) { cairo_xlib_shm_display_t *shm = display->shm; Display *dpy = display->display; XUnmapEvent ev; + flush_events (display); + ev.type = UnmapNotify; ev.event = DefaultRootWindow (dpy); ev.window = shm->window; ev.from_configure = False; + shm->last_event = NextRequest (dpy); XSendEvent (dpy, ev.event, False, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent *)&ev); + shm->pending_events++; } static void @@ -704,22 +748,6 @@ cleanup_shm: return NULL; } -void -_cairo_xlib_display_flush_shm (cairo_xlib_display_t *display) -{ - cairo_xlib_shm_display_t *shm; - XEvent ev; - - shm = display->shm; - if (shm == NULL) - return; - - while (XCheckWindowEvent (display->display, shm->window, - SubstructureRedirectMask | SubstructureNotifyMask, - &ev)) - ; -} - static void _cairo_xlib_surface_update_shm (cairo_xlib_surface_t *surface) { @@ -1160,6 +1188,8 @@ _cairo_xlib_display_init_shm (cairo_xlib_display_t *display) return; } + shm->pending_events = 0; + scr = DefaultScreen (display->display); attr.event_mask = SubstructureRedirectMask | SubstructureNotifyMask; attr.override_redirect = 1; |