summaryrefslogtreecommitdiff
path: root/src/cairo-xlib-surface-shm.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-08-21 10:12:06 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2012-08-21 10:34:23 +0100
commitaa5c7123097c56e2c35bf88b8377bbdd1523fbce (patch)
treeeaf5cde7cb207504cbb5e089c36148232a6c7231 /src/cairo-xlib-surface-shm.c
parent30d09cd33a582a2dd3f3a544366892c724f67592 (diff)
downloadcairo-aa5c7123097c56e2c35bf88b8377bbdd1523fbce.tar.gz
xlib/shm: Use a genuine event rather than an open-ended request
Adding lots of requests without popping the replies causes xcb to continually sort large lists of unprocessed data. Use an event instead and regularly dequeue them. 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.c80
1 files changed, 60 insertions, 20 deletions
diff --git a/src/cairo-xlib-surface-shm.c b/src/cairo-xlib-surface-shm.c
index 7b27f251d..d10e8a6d0 100644
--- a/src/cairo-xlib-surface-shm.c
+++ b/src/cairo-xlib-surface-shm.c
@@ -103,6 +103,7 @@ struct pqueue {
struct _cairo_xlib_shm_display {
int has_pixmaps;
+ Window window;
cairo_list_t pool;
struct pqueue info;
@@ -285,13 +286,32 @@ can_use_shm (Display *dpy, int *has_pixmap)
return success && ! _x_error_occurred;
}
-static void trigger_event (Display *dpy)
+static inline Display *
+peek_display (cairo_device_t *device)
{
- xReq *req;
+ return ((cairo_xlib_display_t *)device)->display;
+}
- LockDisplay(dpy);
- GetEmptyReq(GetInputFocus, req);
- UnlockDisplay(dpy);
+static inline unsigned long
+peek_processed (cairo_device_t *device)
+{
+ return LastKnownRequestProcessed (peek_display(device));
+}
+
+static void trigger_event (cairo_xlib_display_t *display)
+{
+ cairo_xlib_shm_display_t *shm = display->shm;
+ Display *dpy = display->display;
+ XUnmapEvent ev;
+
+ ev.type = UnmapNotify;
+ ev.event = DefaultRootWindow (dpy);
+ ev.window = shm->window;
+ ev.from_configure = False;
+
+ XSendEvent (dpy, ev.event, False,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ (XEvent *)&ev);
}
static void
@@ -443,7 +463,7 @@ _cairo_xlib_shm_pool_create(cairo_xlib_display_t *display,
goto cleanup_detach;
cairo_list_add (&pool->link, &display->shm->pool);
- trigger_event (display->display);
+ trigger_event (display);
*ptr = _cairo_mempool_alloc (&pool->mem, size);
assert (*ptr != NULL);
@@ -497,18 +517,6 @@ _cairo_xlib_shm_info_create (cairo_xlib_display_t *display,
return info;
}
-static inline Display *
-peek_display (cairo_device_t *device)
-{
- return ((cairo_xlib_display_t *)device)->display;
-}
-
-static inline unsigned long
-peek_processed (cairo_device_t *device)
-{
- return LastKnownRequestProcessed (peek_display(device));
-}
-
static cairo_status_t
_cairo_xlib_shm_surface_flush (void *abstract_surface, unsigned flags)
{
@@ -696,6 +704,22 @@ 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)
{
@@ -944,7 +968,7 @@ _cairo_xlib_surface_put_shm (cairo_xlib_surface_t *surface)
_cairo_damage_destroy (damage);
shm->active = NextRequest (display->display);
- trigger_event (display->display);
+ trigger_event (display);
_cairo_xlib_surface_put_gc (display, surface, gc);
out:
@@ -1071,7 +1095,7 @@ _cairo_xlib_shm_surface_mark_active (cairo_surface_t *surface)
shm = (cairo_xlib_shm_surface_t *) surface;
shm->active = next_request (surface->device);
- trigger_event (peek_display (surface->device));
+ trigger_event ((cairo_xlib_display_t *)shm->image.base.device);
}
XRenderPictFormat *
@@ -1119,6 +1143,8 @@ _cairo_xlib_display_init_shm (cairo_xlib_display_t *display)
{
int has_pixmap;
cairo_xlib_shm_display_t *shm;
+ XSetWindowAttributes attr;
+ int scr;
display->shm = NULL;
@@ -1134,6 +1160,17 @@ _cairo_xlib_display_init_shm (cairo_xlib_display_t *display)
return;
}
+ scr = DefaultScreen (display->display);
+ attr.event_mask = SubstructureRedirectMask | SubstructureNotifyMask;
+ attr.override_redirect = 1;
+ shm->window = XCreateWindow (display->display,
+ DefaultRootWindow (display->display), -1, -1,
+ 1, 1, 0,
+ DefaultDepth (display->display, scr),
+ InputOutput,
+ DefaultVisual (display->display, scr),
+ CWEventMask | CWOverrideRedirect, &attr);
+
shm->has_pixmaps = has_pixmap ? MIN_PIXMAP_SIZE : 0;
cairo_list_init (&shm->pool);
@@ -1157,6 +1194,9 @@ _cairo_xlib_display_fini_shm (cairo_xlib_display_t *display)
_cairo_xlib_display_shm_pool_destroy (display, pool);
}
+ if (display->display)
+ XDestroyWindow (display->display, shm->window);
+
free (shm);
display->shm = NULL;
}