[cairo-commit] 2 commits - boilerplate/cairo-boilerplate-xcb.c src/cairo-xcb-surface-render.c

Uli Schlachter psychon at kemper.freedesktop.org
Fri Mar 4 07:37:35 PST 2011


 boilerplate/cairo-boilerplate-xcb.c |    1 
 src/cairo-xcb-surface-render.c      |   77 +++++++-----------------------------
 2 files changed, 15 insertions(+), 63 deletions(-)

New commits:
commit f1d313e042af89b2f5f5d09d3eb1703d0517ecd7
Author: Uli Schlachter <psychon at znc.in>
Date:   Thu Mar 3 19:14:36 2011 +0100

    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 <psychon at znc.in>

diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c
index cb81507..8829dda 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;
 }
commit f9344911250ea347fb0eb54d7ab1f97c8f685a20
Author: Uli Schlachter <psychon at znc.in>
Date:   Sun Feb 13 19:40:57 2011 +0100

    xcb boilerplate: Handle device offsets correctly
    
    When running cairo-test-suite with "-a", backends are also tested with a
    non-zero device offset. However, for "xcb-window&" the boilerplate incorrectly
    overwrote the device offset with a zero offset again.
    
    This caused all test results to be offset by 25 pixels which obviously makes all
    tests fail.
    
    Just removing the call to cairo_surface_set_device_offset solves the problem.
    
    Signed-off-by: Uli Schlachter <psychon at znc.in>

diff --git a/boilerplate/cairo-boilerplate-xcb.c b/boilerplate/cairo-boilerplate-xcb.c
index b1bf4de..c5dee8e 100644
--- a/boilerplate/cairo-boilerplate-xcb.c
+++ b/boilerplate/cairo-boilerplate-xcb.c
@@ -635,7 +635,6 @@ _cairo_boilerplate_xcb_finish_surface (cairo_surface_t *surface)
 	cairo_t *cr;
 
 	cr = cairo_create (xtc->surface);
-	cairo_surface_set_device_offset (surface, 0, 0);
 	cairo_set_source_surface (cr, surface, 0, 0);
 	cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
 	cairo_paint (cr);


More information about the cairo-commit mailing list