From f1d313e042af89b2f5f5d09d3eb1703d0517ecd7 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Thu, 3 Mar 2011 19:14:36 +0100 Subject: [PATCH] xcb: Remove _cairo_xcb_picture_copy All cairo_xcb_picture_t now get their own, private Picture instead of possibly sharing it with a cairo_xcb_surface_t. This solves a cyclic dependency which caused cairo_xcb_picture_t to be leaked until their device was finished. When an xcb surface was used as a source, a cairo_xcb_picture_t was created which kept a reference to the surface. This picture was then added as a snapshot to the surface which caused the surface to own a reference to the picture. As a result, the Picture and possibly its associated Pixmap were not freed on the X11 server which could thus run out of memory. This change causes more Pictures to be created which could possibly slow down cairo-xcb. There seems to be no measurable difference with cairo-perf-trace. For the micro benchmarks, this has the most impact on paint_similar-rgba_source.512: min(ticks) min(ms) median(ms) stddev. iterations overhead before 158732 0.159 0.159 0.11% 4: 1651.49 after 162579 0.163 0.163 0.18% 4: 1612.41 Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=34912 Signed-off-by: Uli Schlachter --- src/cairo-xcb-surface-render.c | 77 +++++++--------------------------- 1 file changed, 15 insertions(+), 62 deletions(-) diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c index cb8150764..8829dda27 100644 --- a/src/cairo-xcb-surface-render.c +++ b/src/cairo-xcb-surface-render.c @@ -62,8 +62,6 @@ typedef struct _cairo_xcb_picture { cairo_surface_t base; - cairo_surface_t *owner; - cairo_xcb_screen_t *screen; xcb_render_picture_t picture; xcb_render_pictformat_t xrender_format; @@ -105,16 +103,11 @@ _cairo_xcb_picture_finish (void *abstract_surface) cairo_xcb_connection_t *connection = _picture_to_connection (surface); cairo_status_t status; - if (surface->owner != NULL) - cairo_surface_destroy (surface->owner); - status = _cairo_xcb_connection_acquire (connection); if (unlikely (status)) return status; - if (surface->owner == NULL) { - _cairo_xcb_connection_render_free_picture (connection, surface->picture); - } + _cairo_xcb_connection_render_free_picture (connection, surface->picture); _cairo_xcb_connection_release (connection); @@ -152,7 +145,6 @@ _cairo_xcb_picture_create (cairo_xcb_screen_t *screen, _cairo_content_from_pixman_format (pixman_format)); surface->screen = screen; - surface->owner = NULL; surface->picture = _cairo_xcb_connection_get_xid (screen->connection); surface->pixman_format = pixman_format; surface->xrender_format = xrender_format; @@ -170,41 +162,6 @@ _cairo_xcb_picture_create (cairo_xcb_screen_t *screen, return surface; } -static cairo_xcb_picture_t * -_cairo_xcb_picture_copy (cairo_xcb_surface_t *target) -{ - cairo_xcb_picture_t *surface; - - surface = malloc (sizeof (cairo_xcb_picture_t)); - if (unlikely (surface == NULL)) - return (cairo_xcb_picture_t *) - _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - _cairo_surface_init (&surface->base, - &_cairo_xcb_picture_backend, - target->base.device, - target->base.content); - - surface->screen = target->screen; - surface->owner = cairo_surface_reference (&target->base); - _cairo_xcb_surface_ensure_picture (target); - surface->picture = target->picture; - surface->pixman_format = target->pixman_format; - surface->xrender_format = target->xrender_format; - - surface->x0 = surface->y0 = 0; - surface->x = surface->y = 0; - surface->width = target->width; - surface->height = target->height; - - surface->transform = identity_transform; - surface->extend = CAIRO_EXTEND_NONE; - surface->filter = CAIRO_FILTER_NEAREST; - surface->has_component_alpha = FALSE; - - return surface; -} - static inline cairo_bool_t _operator_is_supported (uint32_t flags, cairo_operator_t op) { @@ -978,25 +935,21 @@ _copy_to_picture (cairo_xcb_surface_t *source, if (source->drm != NULL) cairo_surface_flush (source->drm); - if (source->owns_pixmap && ! force) { - picture = _cairo_xcb_picture_copy (source); - } else { - picture = _cairo_xcb_picture_create (source->screen, - source->xrender_format, - source->pixman_format, - source->width, - source->height); - if (unlikely (picture->base.status)) - return picture; + picture = _cairo_xcb_picture_create (source->screen, + source->xrender_format, + source->pixman_format, + source->width, + source->height); + if (unlikely (picture->base.status)) + return picture; - _cairo_xcb_connection_render_create_picture (source->connection, - picture->picture, - source->drawable, - source->xrender_format, - XCB_RENDER_CP_GRAPHICS_EXPOSURE | - XCB_RENDER_CP_SUBWINDOW_MODE, - values); - } + _cairo_xcb_connection_render_create_picture (source->connection, + picture->picture, + source->drawable, + source->xrender_format, + XCB_RENDER_CP_GRAPHICS_EXPOSURE | + XCB_RENDER_CP_SUBWINDOW_MODE, + values); return picture; }