[cairo-commit] 2 commits - boilerplate/cairo-boilerplate.c boilerplate/cairo-boilerplate-glx.c boilerplate/cairo-boilerplate.h boilerplate/cairo-boilerplate-xcb.c boilerplate/cairo-boilerplate-xlib.c perf/cairo-perf-trace.c src/cairo-gl-composite.c src/cairo-xcb-connection.c src/cairo-xcb.h

Chris Wilson ickle at kemper.freedesktop.org
Thu Jun 2 01:00:54 PDT 2011


 boilerplate/cairo-boilerplate-glx.c  |    4 +
 boilerplate/cairo-boilerplate-xcb.c  |   67 ++++++++++++++++++++++++++++++++
 boilerplate/cairo-boilerplate-xlib.c |   58 ++++++++++++++++++++++++++++
 boilerplate/cairo-boilerplate.c      |   72 +++++++++++++++++++++++++++++++++--
 boilerplate/cairo-boilerplate.h      |   11 ++++-
 perf/cairo-perf-trace.c              |   54 ++++++++++++++------------
 src/cairo-gl-composite.c             |    4 -
 src/cairo-xcb-connection.c           |    9 ++++
 src/cairo-xcb.h                      |    3 +
 9 files changed, 250 insertions(+), 32 deletions(-)

New commits:
commit 72b6299c1239c53baa38f44bc898c0c184ce3c71
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jun 2 08:57:19 2011 +0100

    gl: Mark the use-once vertex buffers as DYNAMIC
    
    As we write, use and then immediately discard the vertex buffers, our
    usage pattern more closely matches DYNAMIC (as opposed to STREAM). This
    improve performance by about 10% on intel.
    
    firefox-talos-gfx(snb) 20.226 -> 18.402
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index bb88f59..27912b3 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -1018,7 +1018,7 @@ _cairo_gl_composite_flush (cairo_gl_context_t *ctx)
 	ctx->dispatch.UnmapBuffer (GL_ARRAY_BUFFER);
     else
 	ctx->dispatch.BufferData (GL_ARRAY_BUFFER, ctx->vb_offset,
-				  ctx->vb, GL_STREAM_DRAW);
+				  ctx->vb, GL_DYNAMIC_DRAW);
 
     ctx->vb = NULL;
     ctx->vb_offset = 0;
@@ -1051,7 +1051,7 @@ _cairo_gl_composite_prepare_buffer (cairo_gl_context_t *ctx,
     if (ctx->vb == NULL) {
 	if (ctx->has_map_buffer) {
 	    dispatch->BufferData (GL_ARRAY_BUFFER, CAIRO_GL_VBO_SIZE,
-				  NULL, GL_STREAM_DRAW);
+				  NULL, GL_DYNAMIC_DRAW);
 	    ctx->vb = dispatch->MapBuffer (GL_ARRAY_BUFFER, GL_WRITE_ONLY);
 	}
 	else {
commit bf1b08d066ebcffa71f5e728dc333f4494ff4ba3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jun 1 23:03:36 2011 +0100

    perf

diff --git a/boilerplate/cairo-boilerplate-glx.c b/boilerplate/cairo-boilerplate-glx.c
index f419070..690844e 100644
--- a/boilerplate/cairo-boilerplate-glx.c
+++ b/boilerplate/cairo-boilerplate-glx.c
@@ -373,6 +373,7 @@ static const cairo_boilerplate_target_t targets[] = {
 	CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1,
 	"cairo_gl_surface_create",
 	_cairo_boilerplate_gl_create_surface,
+	cairo_surface_create_similar,
 	NULL, NULL,
 	_cairo_boilerplate_get_image_surface,
 	cairo_surface_write_to_png,
@@ -386,6 +387,7 @@ static const cairo_boilerplate_target_t targets[] = {
 	CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR, 1,
 	"cairo_gl_surface_create",
 	_cairo_boilerplate_gl_create_surface,
+	cairo_surface_create_similar,
 	NULL, NULL,
 	_cairo_boilerplate_get_image_surface,
 	cairo_surface_write_to_png,
@@ -399,6 +401,7 @@ static const cairo_boilerplate_target_t targets[] = {
 	CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1,
 	"cairo_gl_surface_create_for_window",
 	_cairo_boilerplate_gl_create_window,
+	cairo_surface_create_similar,
 	NULL,
 	_cairo_boilerplate_gl_finish_window,
 	_cairo_boilerplate_get_image_surface,
@@ -413,6 +416,7 @@ static const cairo_boilerplate_target_t targets[] = {
 	CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1,
 	"cairo_gl_surface_create_for_window",
 	_cairo_boilerplate_gl_create_window_db,
+	cairo_surface_create_similar,
 	NULL,
 	_cairo_boilerplate_gl_finish_window,
 	_cairo_boilerplate_get_image_surface,
diff --git a/boilerplate/cairo-boilerplate-xcb.c b/boilerplate/cairo-boilerplate-xcb.c
index 418e138..7cccbda 100644
--- a/boilerplate/cairo-boilerplate-xcb.c
+++ b/boilerplate/cairo-boilerplate-xcb.c
@@ -170,6 +170,66 @@ find_depth (xcb_connection_t  *connection,
     return NULL;
 }
 
+static const cairo_user_data_key_t key;
+
+struct similar {
+    xcb_connection_t *connection;
+    xcb_drawable_t pixmap;
+};
+
+static void _destroy_similar (void *closure)
+{
+    struct similar *similar = closure;
+
+    xcb_free_pixmap (similar->connection, similar->pixmap);
+    free (similar);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_xcb_create_similar (cairo_surface_t *other,
+				       cairo_content_t content,
+				       int width, int height)
+{
+    xcb_screen_t *root;
+    cairo_surface_t *surface;
+    struct similar *similar;
+    xcb_render_pictforminfo_t *render_format;
+    int depth;
+    void *formats;
+
+    similar = malloc (sizeof (*similar));
+
+    switch (content) {
+    default:
+    case CAIRO_CONTENT_COLOR_ALPHA: depth = 32; break;
+    case CAIRO_CONTENT_COLOR: depth = 24; break;
+    case CAIRO_CONTENT_ALPHA: depth = 8; break;
+    }
+
+    similar->connection =
+	cairo_xcb_device_get_connection (cairo_surface_get_device(other));
+    similar->pixmap = xcb_generate_id (similar->connection);
+
+    root = xcb_setup_roots_iterator(xcb_get_setup(similar->connection)).data;
+    xcb_create_pixmap (similar->connection, depth,
+		       similar->pixmap, root->root,
+		       width, height);
+
+    render_format = find_depth (similar->connection, depth, &formats);
+    if (render_format == NULL)
+	return NULL;
+
+    surface = cairo_xcb_surface_create_with_xrender_format (similar->connection,
+							    root,
+							    similar->pixmap,
+							    render_format,
+							    width, height);
+    cairo_surface_set_user_data (surface, &key, similar, _destroy_similar);
+    free(formats);
+
+    return surface;
+}
+
 static cairo_surface_t *
 _cairo_boilerplate_xcb_create_surface (const char		 *name,
 				       cairo_content_t		  content,
@@ -681,6 +741,7 @@ static const cairo_boilerplate_target_t targets[] = {
 	CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR_ALPHA, 1,
 	"cairo_xcb_surface_create_with_xrender_format",
 	_cairo_boilerplate_xcb_create_surface,
+	_cairo_boilerplate_xcb_create_similar,
 	NULL,
 	_cairo_boilerplate_xcb_finish_surface,
 	_cairo_boilerplate_get_image_surface,
@@ -695,6 +756,7 @@ static const cairo_boilerplate_target_t targets[] = {
 	CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR, 1,
 	"cairo_xcb_surface_create_with_xrender_format",
 	_cairo_boilerplate_xcb_create_surface,
+	_cairo_boilerplate_xcb_create_similar,
 	NULL,
 	_cairo_boilerplate_xcb_finish_surface,
 	_cairo_boilerplate_get_image_surface,
@@ -709,6 +771,7 @@ static const cairo_boilerplate_target_t targets[] = {
 	CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR, 1,
 	"cairo_xcb_surface_create_with_xrender_format",
 	_cairo_boilerplate_xcb_create_window,
+	_cairo_boilerplate_xcb_create_similar,
 	NULL,
 	_cairo_boilerplate_xcb_finish_surface,
 	_cairo_boilerplate_get_image_surface,
@@ -723,6 +786,7 @@ static const cairo_boilerplate_target_t targets[] = {
 	CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR, 1,
 	"cairo_xcb_surface_create_with_xrender_format",
 	_cairo_boilerplate_xcb_create_window_db,
+	_cairo_boilerplate_xcb_create_similar,
 	NULL,
 	_cairo_boilerplate_xcb_finish_surface,
 	_cairo_boilerplate_get_image_surface,
@@ -737,6 +801,7 @@ static const cairo_boilerplate_target_t targets[] = {
 	CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR_ALPHA, 1,
 	"cairo_xcb_surface_create_with_xrender_format",
 	_cairo_boilerplate_xcb_create_render_0_0,
+	cairo_surface_create_similar,
 	NULL,
 	_cairo_boilerplate_xcb_finish_surface,
 	_cairo_boilerplate_get_image_surface,
@@ -751,6 +816,7 @@ static const cairo_boilerplate_target_t targets[] = {
 	CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR, 1,
 	"cairo_xcb_surface_create_with_xrender_format",
 	_cairo_boilerplate_xcb_create_render_0_0,
+	cairo_surface_create_similar,
 	NULL,
 	_cairo_boilerplate_xcb_finish_surface,
 	_cairo_boilerplate_get_image_surface,
@@ -765,6 +831,7 @@ static const cairo_boilerplate_target_t targets[] = {
 	CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR, 1,
 	"cairo_xcb_surface_create_with_xrender_format",
 	_cairo_boilerplate_xcb_create_fallback,
+	cairo_surface_create_similar,
 	NULL,
 	_cairo_boilerplate_xcb_finish_surface,
 	_cairo_boilerplate_get_image_surface,
diff --git a/boilerplate/cairo-boilerplate-xlib.c b/boilerplate/cairo-boilerplate-xlib.c
index f82b78b..797fe97 100644
--- a/boilerplate/cairo-boilerplate-xlib.c
+++ b/boilerplate/cairo-boilerplate-xlib.c
@@ -35,6 +35,8 @@
 
 #include <X11/Xutil.h> /* for XDestroyImage */
 
+static const cairo_user_data_key_t key;
+
 typedef struct _xlib_target_closure {
     Display *dpy;
     Drawable drawable;
@@ -215,6 +217,58 @@ _cairo_boilerplate_xlib_perf_create_surface (Display		   *dpy,
 							  width, height);
 }
 
+struct similar {
+	Display *dpy;
+	Pixmap pixmap;
+};
+
+static void _destroy_similar (void *closure)
+{
+    struct similar *similar = closure;
+
+    XFreePixmap (similar->dpy, similar->pixmap);
+    free (similar);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_xlib_create_similar (cairo_surface_t		*other,
+					cairo_content_t		 content,
+					int			 width,
+					int			 height)
+{
+    XRenderPictFormat *xrender_format;
+    uint32_t format;
+    struct similar *similar;
+    cairo_surface_t *surface;
+
+    similar = malloc (sizeof (*similar));
+    similar->dpy = cairo_xlib_surface_get_display (other);
+
+    switch (content) {
+    default:
+    case CAIRO_CONTENT_COLOR_ALPHA: format = PictStandardARGB32; break;
+    case CAIRO_CONTENT_COLOR: format = PictStandardRGB24; break;
+    case CAIRO_CONTENT_ALPHA: format = PictStandardA8; break;
+    }
+
+    xrender_format = XRenderFindStandardFormat (similar->dpy, format);
+    similar->pixmap = XCreatePixmap (similar->dpy,
+				     DefaultRootWindow (similar->dpy),
+				     width, height,
+				     xrender_format->depth);
+
+    surface =
+	    cairo_xlib_surface_create_with_xrender_format (similar->dpy,
+							   similar->pixmap,
+							   DefaultScreenOfDisplay (similar->dpy),
+							   xrender_format,
+							   width, height);
+
+    cairo_surface_set_user_data (surface, &key, similar, _destroy_similar);
+
+    return surface;
+}
+
 static cairo_surface_t *
 _cairo_boilerplate_xlib_create_surface (const char		  *name,
 					cairo_content_t 	   content,
@@ -511,6 +565,7 @@ static const cairo_boilerplate_target_t targets[] = {
 	CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR_ALPHA, 1,
 	"cairo_xlib_surface_create_with_xrender_format",
 	_cairo_boilerplate_xlib_create_surface,
+	_cairo_boilerplate_xlib_create_similar,
 	NULL, NULL,
 	_cairo_boilerplate_get_image_surface,
 	cairo_surface_write_to_png,
@@ -524,6 +579,7 @@ static const cairo_boilerplate_target_t targets[] = {
 	CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1,
 	"cairo_xlib_surface_create_with_xrender_format",
 	_cairo_boilerplate_xlib_create_surface,
+	_cairo_boilerplate_xlib_create_similar,
 	NULL, NULL,
 	_cairo_boilerplate_get_image_surface,
 	cairo_surface_write_to_png,
@@ -537,6 +593,7 @@ static const cairo_boilerplate_target_t targets[] = {
 	CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1,
 	"cairo_xlib_surface_create",
 	_cairo_boilerplate_xlib_window_create_surface,
+	cairo_surface_create_similar,
 	NULL, NULL,
 	_cairo_boilerplate_get_image_surface,
 	cairo_surface_write_to_png,
@@ -554,6 +611,7 @@ static const cairo_boilerplate_target_t targets[] = {
 	CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1,
 	"cairo_xlib_surface_create",
 	_cairo_boilerplate_xlib_fallback_create_surface,
+	cairo_surface_create_similar,
 	NULL, NULL,
 	_cairo_boilerplate_get_image_surface,
 	cairo_surface_write_to_png,
diff --git a/boilerplate/cairo-boilerplate.c b/boilerplate/cairo-boilerplate.c
index a77fa57..b89e6d8 100644
--- a/boilerplate/cairo-boilerplate.c
+++ b/boilerplate/cairo-boilerplate.c
@@ -151,6 +151,35 @@ _cairo_boilerplate_image_create_surface (const char		   *name,
     return cairo_image_surface_create (format, ceil (width), ceil (height));
 }
 
+static const cairo_user_data_key_t key;
+
+static cairo_surface_t *
+_cairo_boilerplate_image_create_similar (cairo_surface_t *other,
+					 cairo_content_t content,
+					 int width, int height)
+{
+    cairo_format_t format;
+    cairo_surface_t *surface;
+    int stride;
+    void *ptr;
+
+    switch (content) {
+    case CAIRO_CONTENT_ALPHA: format = CAIRO_FORMAT_A8; break;
+    case CAIRO_CONTENT_COLOR: format = CAIRO_FORMAT_RGB24; break;
+    default:
+    case CAIRO_CONTENT_COLOR_ALPHA: format = CAIRO_FORMAT_ARGB32; break;
+    }
+
+    stride = cairo_format_stride_for_width(format, width);
+    ptr = malloc (stride* height);
+
+    surface = cairo_image_surface_create_for_data (ptr, format,
+						   width, height, stride);
+    cairo_surface_set_user_data (surface, &key, ptr, free);
+
+    return surface;
+}
+
 static cairo_surface_t *
 _cairo_boilerplate_image16_create_surface (const char		     *name,
 					   cairo_content_t	      content,
@@ -160,7 +189,7 @@ _cairo_boilerplate_image16_create_surface (const char		     *name,
 					   double		      max_height,
 					   cairo_boilerplate_mode_t   mode,
 					   int			      id,
-					   void 		    **closure)
+					   void			    **closure)
 {
     *closure = NULL;
 
@@ -168,6 +197,33 @@ _cairo_boilerplate_image16_create_surface (const char		     *name,
     return cairo_image_surface_create (CAIRO_FORMAT_RGB16_565, ceil (width), ceil (height));
 }
 
+static cairo_surface_t *
+_cairo_boilerplate_image16_create_similar (cairo_surface_t *other,
+					   cairo_content_t content,
+					   int width, int height)
+{
+    cairo_format_t format;
+    cairo_surface_t *surface;
+    int stride;
+    void *ptr;
+
+    switch (content) {
+    case CAIRO_CONTENT_ALPHA: format = CAIRO_FORMAT_A8; break;
+    case CAIRO_CONTENT_COLOR: format = CAIRO_FORMAT_RGB16_565; break;
+    default:
+    case CAIRO_CONTENT_COLOR_ALPHA: format = CAIRO_FORMAT_ARGB32; break;
+    }
+
+    stride = cairo_format_stride_for_width(format, width);
+    ptr = malloc (stride* height);
+
+    surface = cairo_image_surface_create_for_data (ptr, format,
+						   width, height, stride);
+    cairo_surface_set_user_data (surface, &key, ptr, free);
+
+    return surface;
+}
+
 static char *
 _cairo_boilerplate_image_describe (void *closure)
 {
@@ -334,7 +390,9 @@ static const cairo_boilerplate_target_t builtin_targets[] = {
     {
 	"image", "image", NULL, NULL,
 	CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR_ALPHA, 0,
-	NULL, _cairo_boilerplate_image_create_surface,
+	NULL,
+	_cairo_boilerplate_image_create_surface,
+	_cairo_boilerplate_image_create_similar,
 	NULL, NULL,
 	_cairo_boilerplate_get_image_surface,
 	cairo_surface_write_to_png,
@@ -345,7 +403,9 @@ static const cairo_boilerplate_target_t builtin_targets[] = {
     {
 	"image", "image", NULL, NULL,
 	CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR, 0,
-	NULL, _cairo_boilerplate_image_create_surface,
+	NULL,
+	_cairo_boilerplate_image_create_surface,
+	_cairo_boilerplate_image_create_similar,
 	NULL, NULL,
 	_cairo_boilerplate_get_image_surface,
 	cairo_surface_write_to_png,
@@ -356,7 +416,9 @@ static const cairo_boilerplate_target_t builtin_targets[] = {
     {
 	"image16", "image", NULL, NULL,
 	CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR, 0,
-	NULL, _cairo_boilerplate_image16_create_surface,
+	NULL,
+	_cairo_boilerplate_image16_create_surface,
+	_cairo_boilerplate_image16_create_similar,
 	NULL, NULL,
 	_cairo_boilerplate_get_image_surface,
 	cairo_surface_write_to_png,
@@ -370,6 +432,7 @@ static const cairo_boilerplate_target_t builtin_targets[] = {
 	CAIRO_SURFACE_TYPE_RECORDING, CAIRO_CONTENT_COLOR_ALPHA, 0,
 	"cairo_recording_surface_create",
 	_cairo_boilerplate_recording_create_surface,
+	cairo_surface_create_similar,
 	NULL, NULL,
 	_cairo_boilerplate_get_image_surface,
 	cairo_surface_write_to_png,
@@ -382,6 +445,7 @@ static const cairo_boilerplate_target_t builtin_targets[] = {
 	CAIRO_SURFACE_TYPE_RECORDING, CAIRO_CONTENT_COLOR, 0,
 	"cairo_recording_surface_create",
 	_cairo_boilerplate_recording_create_surface,
+	cairo_surface_create_similar,
 	NULL, NULL,
 	_cairo_boilerplate_get_image_surface,
 	cairo_surface_write_to_png,
diff --git a/boilerplate/cairo-boilerplate.h b/boilerplate/cairo-boilerplate.h
index c0a0452..d145a1e 100644
--- a/boilerplate/cairo-boilerplate.h
+++ b/boilerplate/cairo-boilerplate.h
@@ -126,6 +126,12 @@ typedef cairo_surface_t *
 				       int			  id,
 				       void			**closure);
 
+typedef cairo_surface_t *
+(*cairo_boilerplate_create_similar_t) (cairo_surface_t		 *other,
+				       cairo_content_t		  content,
+				       int			  width,
+				       int			  height);
+
 typedef void
 (*cairo_boilerplate_force_fallbacks_t) (cairo_surface_t *surface,
 				       double		 x_pixels_per_inch,
@@ -163,11 +169,12 @@ typedef struct _cairo_boilerplate_target {
     unsigned int				 error_tolerance;
     const char					*probe; /* runtime dl check */
     cairo_boilerplate_create_surface_t		 create_surface;
-    cairo_boilerplate_force_fallbacks_t 	 force_fallbacks;
+    cairo_boilerplate_create_similar_t		 create_similar;
+    cairo_boilerplate_force_fallbacks_t		 force_fallbacks;
     cairo_boilerplate_finish_surface_t		 finish_surface;
     cairo_boilerplate_get_image_surface_t	 get_image_surface;
     cairo_boilerplate_write_to_png_t		 write_to_png;
-    cairo_boilerplate_cleanup_t 		 cleanup;
+    cairo_boilerplate_cleanup_t			 cleanup;
     cairo_boilerplate_wait_t			 synchronize;
     cairo_boilerplate_describe_t                 describe;
     cairo_bool_t				 is_measurable;
diff --git a/perf/cairo-perf-trace.c b/perf/cairo-perf-trace.c
index 78c5402..b3d22cf 100644
--- a/perf/cairo-perf-trace.c
+++ b/perf/cairo-perf-trace.c
@@ -68,6 +68,12 @@
 #define CAIRO_PERF_MIN_STD_DEV_COUNT	3
 #define CAIRO_PERF_STABLE_STD_DEV_COUNT 3
 
+struct trace {
+    const cairo_boilerplate_target_t *target;
+    void            *closure;
+    cairo_surface_t *surface;
+};
+
 cairo_bool_t
 cairo_perf_can_run (cairo_perf_t *perf,
 		    const char	 *name,
@@ -203,15 +209,16 @@ scache_remove (void *closure)
 static cairo_surface_t *
 _similar_surface_create (void		 *closure,
 			 cairo_content_t  content,
-			 double 	  width,
-			 double 	  height,
+			 double		  width,
+			 double		  height,
 			 long		  uid)
 {
+    struct trace *args = closure;
     cairo_surface_t *surface;
     struct scache skey, *s;
 
     if (uid == 0 || surface_cache == NULL)
-	return cairo_surface_create_similar (closure, content, width, height);
+	return args->target->create_similar (args->surface, content, width, height);
 
     skey.entry.hash = uid;
     s = _cairo_hash_table_lookup (surface_cache, &skey.entry);
@@ -228,7 +235,7 @@ _similar_surface_create (void		 *closure,
 	 */
     }
 
-    surface = cairo_surface_create_similar (closure, content, width, height);
+    surface = args->target->create_similar (args->surface, content, width, height);
     s = malloc (sizeof (struct scache));
     if (s == NULL)
 	return surface;
@@ -304,8 +311,7 @@ describe (cairo_perf_t *perf,
 
 static void
 execute (cairo_perf_t	 *perf,
-         void            *closure,
-	 cairo_surface_t *target,
+	 struct trace	 *args,
 	 const char	 *trace)
 {
     static cairo_bool_t first_run = TRUE;
@@ -315,7 +321,7 @@ execute (cairo_perf_t	 *perf,
     int low_std_dev_count;
     char *trace_cpy, *name, *dot;
     const cairo_script_interpreter_hooks_t hooks = {
-	.closure = target,
+	.closure = args,
 	.surface_create = _similar_surface_create,
 	.context_create = _context_create
     };
@@ -347,7 +353,7 @@ execute (cairo_perf_t	 *perf,
 	first_run = FALSE;
     }
 
-    describe (perf, closure);
+    describe (perf, args->closure);
 
     times = perf->times;
 
@@ -373,7 +379,7 @@ execute (cairo_perf_t	 *perf,
 	cairo_perf_timer_start ();
 
 	cairo_script_interpreter_run (csi, trace);
-	clear_surface (target); /* queue a write to the sync'ed surface */
+	clear_surface (args->surface); /* queue a write to the sync'ed surface */
 
 	cairo_perf_timer_stop ();
 	times[i] = cairo_perf_timer_elapsed ();
@@ -700,31 +706,31 @@ cairo_perf_trace (cairo_perf_t			   *perf,
 		  const cairo_boilerplate_target_t *target,
 		  const char			   *trace)
 {
-    cairo_surface_t *surface;
-    void *closure;
-
-    surface = (target->create_surface) (NULL,
-					CAIRO_CONTENT_COLOR_ALPHA,
-					1, 1,
-					1, 1,
-					CAIRO_BOILERPLATE_MODE_PERF,
-					0,
-					&closure);
-    if (surface == NULL) {
+    struct trace args;
+
+    args.target = target;
+    args.surface = target->create_surface (NULL,
+					   CAIRO_CONTENT_COLOR_ALPHA,
+					   1, 1,
+					   1, 1,
+					   CAIRO_BOILERPLATE_MODE_PERF,
+					   0,
+					   &args.closure);
+    if (cairo_surface_status (args.surface)) {
 	fprintf (stderr,
 		 "Error: Failed to create target surface: %s\n",
 		 target->name);
 	return;
     }
 
-    cairo_perf_timer_set_synchronize (target->synchronize, closure);
+    cairo_perf_timer_set_synchronize (target->synchronize, args.closure);
 
-    execute (perf, closure, surface, trace);
+    execute (perf, &args, trace);
 
-    cairo_surface_destroy (surface);
+    cairo_surface_destroy (args.surface);
 
     if (target->cleanup)
-	target->cleanup (closure);
+	target->cleanup (args.closure);
 
     cairo_debug_reset_static_data ();
 #if HAVE_FCFINI
diff --git a/src/cairo-xcb-connection.c b/src/cairo-xcb-connection.c
index 56bf5ae..d6f355b 100644
--- a/src/cairo-xcb-connection.c
+++ b/src/cairo-xcb-connection.c
@@ -789,6 +789,15 @@ _cairo_xcb_connection_get_xid (cairo_xcb_connection_t *connection)
     return xid;
 }
 
+xcb_connection_t *
+cairo_xcb_device_get_connection (cairo_device_t *device)
+{
+    if (device->backend->type != CAIRO_DEVICE_TYPE_XCB)
+	    return NULL;
+
+    return ((cairo_xcb_connection_t *)device)->xcb_connection;
+}
+
 /* public (debug) interface */
 
 /**
diff --git a/src/cairo-xcb.h b/src/cairo-xcb.h
index 9a3798d..4bfb0b5 100644
--- a/src/cairo-xcb.h
+++ b/src/cairo-xcb.h
@@ -75,6 +75,9 @@ cairo_xcb_surface_set_size (cairo_surface_t *surface,
 			    int		     width,
 			    int		     height);
 
+cairo_public xcb_connection_t *
+cairo_xcb_device_get_connection (cairo_device_t *device);
+
 /* debug interface */
 
 cairo_public void


More information about the cairo-commit mailing list