summaryrefslogtreecommitdiff
path: root/src/cairo-xlib-surface-shm.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-08-21 21:03:04 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2012-08-21 22:20:02 +0100
commit5c77b4df146796d8280a4f5b16949e3db4a1f84a (patch)
tree8216d8c03138ed46938f896903fa9476dbb84856 /src/cairo-xlib-surface-shm.c
parentaa5c7123097c56e2c35bf88b8377bbdd1523fbce (diff)
downloadcairo-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.c62
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;