From 6ee216000ae487492fceda0fb3fecb20bb9a41f6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 13 Sep 2012 15:25:49 +0100 Subject: xlib: Explicitly discard the fallback shm pixmap upon user modification If the user changes the size of the underlying drawable, we much make sure that we discard the current ShmPixmap in order to create a new fallback pixmap of the correct size next time. Reported-by: Weng Xuetian Bugzilla: https://bugs.freedesktop.org/show_bug.cgi Signed-off-by: Chris Wilson --- src/cairo-xlib-surface.c | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index 913589f5..4d1ef908 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -358,6 +358,22 @@ _cairo_xlib_surface_create_similar (void *abstract_src, return &surface->base; } +static void +_cairo_xlib_surface_discard_shm (cairo_xlib_surface_t *surface) +{ + if (surface->shm == NULL) + return; + + /* Force the flush for an external surface */ + if (!surface->owns_pixmap) + cairo_surface_flush (surface->shm); + + cairo_surface_finish (surface->shm); + cairo_surface_destroy (surface->shm); + + surface->shm = NULL; +} + static cairo_status_t _cairo_xlib_surface_finish (void *abstract_surface) { @@ -378,13 +394,7 @@ _cairo_xlib_surface_finish (void *abstract_surface) if (surface->picture) XRenderFreePicture (display->display, surface->picture); - if (surface->shm) { - /* Force the flush for an external surface */ - if (!surface->owns_pixmap) - cairo_surface_flush (surface->shm); - cairo_surface_finish (surface->shm); - cairo_surface_destroy (surface->shm); - } + _cairo_xlib_surface_discard_shm (surface); if (surface->owns_pixmap) XFreePixmap (display->display, surface->drawable); @@ -2048,6 +2058,9 @@ cairo_xlib_surface_set_size (cairo_surface_t *abstract_surface, return; } + if (surface->width == width && surface->height == height) + return; + if (! valid_size (width, height)) { _cairo_surface_set_error (abstract_surface, _cairo_error (CAIRO_STATUS_INVALID_SIZE)); @@ -2060,9 +2073,12 @@ cairo_xlib_surface_set_size (cairo_surface_t *abstract_surface, return; } + _cairo_xlib_surface_discard_shm (surface); + surface->width = width; surface->height = height; } + /** * cairo_xlib_surface_set_drawable: * @surface: a #cairo_surface_t for the XLib backend @@ -2142,8 +2158,12 @@ cairo_xlib_surface_set_drawable (cairo_surface_t *abstract_surface, surface->drawable = drawable; } - surface->width = width; - surface->height = height; + if (surface->width != width || surface->height != height) { + _cairo_xlib_surface_discard_shm (surface); + + surface->width = width; + surface->height = height; + } } /** -- cgit v1.2.3