diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-08-21 10:12:06 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-08-21 10:34:23 +0100 |
commit | aa5c7123097c56e2c35bf88b8377bbdd1523fbce (patch) | |
tree | eaf5cde7cb207504cbb5e089c36148232a6c7231 /src/cairo-xlib-surface-shm.c | |
parent | 30d09cd33a582a2dd3f3a544366892c724f67592 (diff) | |
download | cairo-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.c | 80 |
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; } |