[cairo-commit] boilerplate/cairo-boilerplate-xcb.c src/cairo-xcb-connection.c src/cairo-xcb-connection-render.c src/cairo-xcb-private.h src/cairo-xcb-screen.c src/cairo-xcb-surface.c src/cairo-xcb-surface-core.c src/cairo-xcb-surface-render.c src/cairo-xlib-xcb-surface.c

Chris Wilson ickle at kemper.freedesktop.org
Mon May 10 05:37:35 PDT 2010


 boilerplate/cairo-boilerplate-xcb.c |   22 +++++++++++--
 src/cairo-xcb-connection-render.c   |   35 ++++++++++++++++------
 src/cairo-xcb-connection.c          |   57 +++++++++++++++++++++++++-----------
 src/cairo-xcb-private.h             |    2 -
 src/cairo-xcb-screen.c              |   15 +++++----
 src/cairo-xcb-surface-core.c        |    1 
 src/cairo-xcb-surface-render.c      |   32 +++++++++++++++++---
 src/cairo-xcb-surface.c             |    5 +--
 src/cairo-xlib-xcb-surface.c        |    1 
 9 files changed, 123 insertions(+), 47 deletions(-)

New commits:
commit e540d040bddc717f17e0e2510cffc0bc3cb41ccd
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon May 10 13:36:53 2010 +0100

    xcb: trivial memfault fixes.
    
    The first fixes required to kick-start memfault testing of the xcb
    backend.

diff --git a/boilerplate/cairo-boilerplate-xcb.c b/boilerplate/cairo-boilerplate-xcb.c
index 5ddf3fa..0a5f5a4 100644
--- a/boilerplate/cairo-boilerplate-xcb.c
+++ b/boilerplate/cairo-boilerplate-xcb.c
@@ -128,8 +128,10 @@ _cairo_boilerplate_xcb_create_surface (const char		 *name,
 	height = 1;
 
     xtc->c = c = xcb_connect(NULL,NULL);
-    if (xcb_connection_has_error(c))
+    if (c == NULL || xcb_connection_has_error(c)) {
+	free (xtc);
 	return NULL;
+    }
 
     root = xcb_setup_roots_iterator(xcb_get_setup(c)).data;
 
@@ -233,8 +235,10 @@ _cairo_boilerplate_xcb_create_window (const char		 *name,
 	height = 1;
 
     xtc->c = c = xcb_connect(NULL,NULL);
-    if (xcb_connection_has_error(c))
+    if (xcb_connection_has_error(c)) {
+	free (xtc);
 	return NULL;
+    }
 
     xtc->surface = NULL;
 
@@ -302,8 +306,10 @@ _cairo_boilerplate_xcb_create_window_db (const char		 *name,
 	height = 1;
 
     xtc->c = c = xcb_connect(NULL,NULL);
-    if (xcb_connection_has_error(c))
+    if (xcb_connection_has_error(c)) {
+	free (xtc);
 	return NULL;
+    }
 
     xtc->surface = NULL;
 
@@ -374,8 +380,10 @@ _cairo_boilerplate_xcb_create_render_0_0 (const char		 *name,
 	height = 1;
 
     xtc->c = c = xcb_connect(NULL,NULL);
-    if (xcb_connection_has_error(c))
+    if (xcb_connection_has_error(c)) {
+	free (xtc);
 	return NULL;
+    }
 
     root = xcb_setup_roots_iterator(xcb_get_setup(c)).data;
 
@@ -422,6 +430,12 @@ _cairo_boilerplate_xcb_create_render_0_0 (const char		 *name,
 							xtc->drawable,
 							render_format,
 							width, height);
+    if (cairo_surface_status (tmp)) {
+	free (formats);
+	xcb_disconnect (c);
+	free (xtc);
+	return tmp;
+    }
 
     cairo_xcb_device_debug_cap_xrender_version (cairo_surface_get_device (tmp),
                                                 0, 0);
diff --git a/src/cairo-xcb-connection-render.c b/src/cairo-xcb-connection-render.c
index 97f8cce..63eb59d 100644
--- a/src/cairo-xcb-connection-render.c
+++ b/src/cairo-xcb-connection-render.c
@@ -733,25 +733,42 @@ _cairo_xcb_connection_render_fill_rectangles (cairo_xcb_connection_t      *conne
 	uint32_t dst;
 	xcb_render_color_t     color;
     } req;
-    struct iovec vec[2];
-    uint32_t len = (sizeof (req) + num_rects * sizeof (xcb_rectangle_t)) >> 2;
+    struct iovec vec[3];
+    uint32_t prefix[2];
+    uint32_t len;
 
     COMPILE_TIME_ASSERT (sizeof (req) == 20);
-    assert(len < connection->root->maximum_request_length);
 
     req.major = connection->render->major_opcode;
     req.minor = 26;
-    req.length = (sizeof (req) + num_rects * sizeof (xcb_rectangle_t)) >> 2;
     req.op = op;
     req.dst = dst;
     req.color = color;
 
-    vec[0].iov_base = &req;
-    vec[0].iov_len = sizeof (req);
-    vec[1].iov_base = rects;
-    vec[1].iov_len = num_rects * sizeof (xcb_rectangle_t);
+    len = (sizeof (req) + num_rects * sizeof (xcb_rectangle_t)) >> 2;
+    if (len < connection->root->maximum_request_length) {
+	req.length = len;
 
-    _cairo_xcb_connection_write (connection, vec, 2);
+	vec[0].iov_base = &req;
+	vec[0].iov_len = sizeof (req);
+
+	len = 1;
+    } else {
+	prefix[0] = *(uint32_t *) &req;
+	prefix[1] = len + 1;
+	vec[0].iov_base = prefix;
+	vec[0].iov_len = sizeof (prefix);
+	vec[1].iov_base = (uint32_t *) &req + 1;
+	vec[1].iov_len = sizeof (req) - 4;
+
+	len = 2;
+    }
+
+    vec[len].iov_base = rects;
+    vec[len].iov_len = num_rects * sizeof (xcb_rectangle_t);
+    len++;
+
+    _cairo_xcb_connection_write (connection, vec, len);
 }
 
 void
diff --git a/src/cairo-xcb-connection.c b/src/cairo-xcb-connection.c
index 25e821e..9da4eb3 100644
--- a/src/cairo-xcb-connection.c
+++ b/src/cairo-xcb-connection.c
@@ -594,6 +594,8 @@ _cairo_xcb_connection_get (xcb_connection_t *xcb_connection)
     const xcb_query_extension_reply_t *ext;
     cairo_status_t status;
 
+    CAIRO_MUTEX_INITIALIZE ();
+
     CAIRO_MUTEX_LOCK (_cairo_xcb_connections_mutex);
     if (connections.next == NULL) {
 	/* XXX _cairo_init () */
@@ -619,31 +621,29 @@ _cairo_xcb_connection_get (xcb_connection_t *xcb_connection)
 	goto unlock;
 
     _cairo_device_init (&connection->device, &_cairo_xcb_device_backend);
-    CAIRO_MUTEX_INIT (connection->shm_mutex);
-    CAIRO_MUTEX_INIT (connection->screens_mutex);
 
     connection->xcb_connection = xcb_connection;
     connection->has_socket = FALSE;
 
-    xcb_prefetch_extension_data (xcb_connection, &xcb_big_requests_id);
-    xcb_prefetch_extension_data (xcb_connection, &xcb_render_id);
-#if CAIRO_HAS_XCB_SHM_FUNCTIONS
-    xcb_prefetch_extension_data (xcb_connection, &xcb_shm_id);
-#endif
-#if 0
-    xcb_prefetch_extension_data (xcb_connection, &xcb_cairo_id);
-#endif
-#if CAIRO_HAS_XCB_DRM_FUNCTIONS
-    xcb_prefetch_extension_data (xcb_connection, &xcb_dri2_id);
-#endif
-
-    xcb_prefetch_maximum_request_length (xcb_connection);
-
     cairo_list_init (&connection->fonts);
     cairo_list_init (&connection->screens);
-    cairo_list_add (&connection->link, &connections);
+    cairo_list_init (&connection->link);
     connection->xrender_formats = _cairo_hash_table_create (_xrender_formats_equal);
+    if (connection->xrender_formats == NULL) {
+	CAIRO_MUTEX_FINI (connection->device.mutex);
+	free (connection);
+	connection = NULL;
+	goto unlock;
+    }
+
     connection->visual_to_xrender_format = _cairo_hash_table_create (_xrender_formats_equal);
+    if (connection->visual_to_xrender_format == NULL) {
+	_cairo_hash_table_destroy (connection->xrender_formats);
+	CAIRO_MUTEX_FINI (connection->device.mutex);
+	free (connection);
+	connection = NULL;
+	goto unlock;
+    }
 
     cairo_list_init (&connection->free_xids);
     _cairo_freepool_init (&connection->xid_pool,
@@ -656,14 +656,34 @@ _cairo_xcb_connection_get (xcb_connection_t *xcb_connection)
     connection->maximum_request_length =
 	xcb_get_maximum_request_length (xcb_connection);
 
+    CAIRO_MUTEX_INIT (connection->shm_mutex);
+    CAIRO_MUTEX_INIT (connection->screens_mutex);
+
+    CAIRO_MUTEX_LOCK (connection->device.mutex);
+
     connection->flags = 0;
 
+    xcb_prefetch_extension_data (xcb_connection, &xcb_big_requests_id);
+    xcb_prefetch_extension_data (xcb_connection, &xcb_render_id);
+#if CAIRO_HAS_XCB_SHM_FUNCTIONS
+    xcb_prefetch_extension_data (xcb_connection, &xcb_shm_id);
+#endif
+#if 0
+    xcb_prefetch_extension_data (xcb_connection, &xcb_cairo_id);
+#endif
+#if CAIRO_HAS_XCB_DRM_FUNCTIONS
+    xcb_prefetch_extension_data (xcb_connection, &xcb_dri2_id);
+#endif
+
+    xcb_prefetch_maximum_request_length (xcb_connection);
+
     connection->root = xcb_get_setup (xcb_connection);
     connection->render = NULL;
     ext = xcb_get_extension_data (xcb_connection, &xcb_render_id);
     if (ext != NULL && ext->present) {
 	status = _cairo_xcb_connection_query_render (connection);
 	if (unlikely (status)) {
+	    CAIRO_MUTEX_UNLOCK (connection->device.mutex);
 	    _cairo_xcb_connection_destroy (connection);
 	    connection = NULL;
 	    goto unlock;
@@ -696,6 +716,9 @@ _cairo_xcb_connection_get (xcb_connection_t *xcb_connection)
     }
 #endif
 
+    CAIRO_MUTEX_UNLOCK (connection->device.mutex);
+
+    cairo_list_add (&connection->link, &connections);
 unlock:
     CAIRO_MUTEX_UNLOCK (_cairo_xcb_connections_mutex);
 
diff --git a/src/cairo-xcb-private.h b/src/cairo-xcb-private.h
index 1c8fc41..e066911 100644
--- a/src/cairo-xcb-private.h
+++ b/src/cairo-xcb-private.h
@@ -437,7 +437,7 @@ cairo_private void
 _cairo_xcb_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph,
 				      cairo_scaled_font_t  *scaled_font);
 
-cairo_private void
+cairo_private cairo_status_t
 _cairo_xcb_surface_clear (cairo_xcb_surface_t *dst);
 
 cairo_private cairo_status_t
diff --git a/src/cairo-xcb-screen.c b/src/cairo-xcb-screen.c
index 0c44e4d..c80bf2d 100644
--- a/src/cairo-xcb-screen.c
+++ b/src/cairo-xcb-screen.c
@@ -247,6 +247,11 @@ _cairo_xcb_screen_get (xcb_connection_t *xcb_connection,
     screen->connection = connection;
     screen->xcb_screen = xcb_screen;
 
+    _cairo_freelist_init (&screen->pattern_cache_entry_freelist,
+			  sizeof (struct pattern_cache_entry));
+    cairo_list_init (&screen->link);
+    cairo_list_init (&screen->surfaces);
+
     if (connection->flags & CAIRO_XCB_HAS_DRI2)
 	screen->device = _xcb_drm_device (xcb_connection, xcb_screen);
     else
@@ -283,25 +288,21 @@ _cairo_xcb_screen_get (xcb_connection_t *xcb_connection,
     if (unlikely (status))
 	goto error_linear;
 
-    _cairo_freelist_init (&screen->pattern_cache_entry_freelist,
-			  sizeof (struct pattern_cache_entry));
-
     cairo_list_add (&screen->link, &connection->screens);
-    cairo_list_init (&screen->surfaces);
 
 unlock:
     CAIRO_MUTEX_UNLOCK (connection->screens_mutex);
 
     return screen;
 
-error_surface:
-    _cairo_cache_fini (&screen->surface_pattern_cache);
 error_linear:
     _cairo_cache_fini (&screen->linear_pattern_cache);
+error_surface:
+    _cairo_cache_fini (&screen->surface_pattern_cache);
 error_screen:
+    CAIRO_MUTEX_UNLOCK (connection->screens_mutex);
     cairo_device_destroy (screen->device);
     free (screen);
-    CAIRO_MUTEX_UNLOCK (connection->screens_mutex);
 
     return NULL;
 }
diff --git a/src/cairo-xcb-surface-core.c b/src/cairo-xcb-surface-core.c
index 2a903a0..3fbb072 100644
--- a/src/cairo-xcb-surface-core.c
+++ b/src/cairo-xcb-surface-core.c
@@ -363,7 +363,6 @@ _cairo_xcb_surface_pixmap (cairo_xcb_surface_t *target,
 {
     cairo_surface_t *source;
     cairo_xcb_pixmap_t *pixmap;
-    cairo_status_t status;
 
     source =  pattern->surface;
     pixmap = (cairo_xcb_pixmap_t *)
diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c
index c108bae..9c2d462 100644
--- a/src/cairo-xcb-surface-render.c
+++ b/src/cairo-xcb-surface-render.c
@@ -2335,11 +2335,22 @@ _cairo_xcb_surface_fixup_unbounded_boxes (cairo_xcb_surface_t *dst,
     return status;
 }
 
-void
+cairo_status_t
 _cairo_xcb_surface_clear (cairo_xcb_surface_t *dst)
 {
     xcb_gcontext_t gc;
     xcb_rectangle_t rect;
+    cairo_status_t status;
+
+    status = _cairo_xcb_connection_acquire (dst->connection);
+    if (unlikely (status))
+	return status;
+
+    status = _cairo_xcb_connection_take_socket (dst->connection);
+    if (unlikely (status)) {
+	_cairo_xcb_connection_release (dst->connection);
+	return status;
+    }
 
     gc = _cairo_xcb_screen_get_gc (dst->screen, dst->drawable, dst->depth);
 
@@ -2353,7 +2364,10 @@ _cairo_xcb_surface_clear (cairo_xcb_surface_t *dst)
 
     _cairo_xcb_screen_put_gc (dst->screen, dst->depth, gc);
 
+    _cairo_xcb_connection_release (dst->connection);
+
     dst->deferred_clear = FALSE;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
@@ -2405,8 +2419,13 @@ _clip_and_composite (cairo_xcb_surface_t	*dst,
 	return status;
     }
 
-    if (dst->deferred_clear)
-	_cairo_xcb_surface_clear (dst);
+    if (dst->deferred_clear) {
+	status = _cairo_xcb_surface_clear (dst);
+	if (unlikely (status)) {
+	    _cairo_xcb_connection_release (dst->connection);
+	    return status;
+	}
+    }
 
     _cairo_xcb_surface_ensure_picture (dst);
 
@@ -2745,8 +2764,11 @@ _clip_and_composite_boxes (cairo_xcb_surface_t *dst,
     if ((dst->flags & CAIRO_XCB_RENDER_HAS_COMPOSITE) == 0)
 	return _core_boxes (dst, op, src, boxes, antialias, clip, extents);
 
-    if (dst->deferred_clear)
-	_cairo_xcb_surface_clear (dst);
+    if (dst->deferred_clear) {
+	status = _cairo_xcb_surface_clear (dst);
+	if (unlikely (status))
+	    return status;
+    }
 
     /* Use a fast path if the boxes are pixel aligned */
     status = _composite_boxes (dst, op, src, boxes, antialias, clip, extents);
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index 7b72832..49b2dfb 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -687,10 +687,11 @@ _cairo_xcb_surface_flush (void *abstract_surface)
 	return surface->drm->backend->flush (surface->drm);
 
     if (likely (surface->fallback == NULL)) {
+	status = CAIRO_STATUS_SUCCESS;
 	if (! surface->base.finished && surface->deferred_clear)
-	    _cairo_xcb_surface_clear (surface);
+	    status = _cairo_xcb_surface_clear (surface);
 
-	return CAIRO_STATUS_SUCCESS;
+	return status;
     }
 
     status = surface->base.status;
diff --git a/src/cairo-xlib-xcb-surface.c b/src/cairo-xlib-xcb-surface.c
index 7e674bf..84e9e33 100644
--- a/src/cairo-xlib-xcb-surface.c
+++ b/src/cairo-xlib-xcb-surface.c
@@ -346,7 +346,6 @@ static xcb_screen_t *
 _cairo_xcb_screen_from_root (xcb_connection_t *connection,
 			     xcb_window_t id)
 {
-    xcb_depth_iterator_t d;
     xcb_screen_iterator_t s;
 
     s = xcb_setup_roots_iterator (xcb_get_setup (connection));


More information about the cairo-commit mailing list