summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-05-10 13:36:53 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2010-05-10 13:36:53 +0100
commite540d040bddc717f17e0e2510cffc0bc3cb41ccd (patch)
treee5a76a9cd0c0f23d708cd6bd14136565bbbb13bf
parent8b486db9a9d74b40df296382eb1833bc40ae791a (diff)
xcb: trivial memfault fixes.
The first fixes required to kick-start memfault testing of the xcb backend.
-rw-r--r--boilerplate/cairo-boilerplate-xcb.c22
-rw-r--r--src/cairo-xcb-connection-render.c35
-rw-r--r--src/cairo-xcb-connection.c57
-rw-r--r--src/cairo-xcb-private.h2
-rw-r--r--src/cairo-xcb-screen.c15
-rw-r--r--src/cairo-xcb-surface-core.c1
-rw-r--r--src/cairo-xcb-surface-render.c32
-rw-r--r--src/cairo-xcb-surface.c5
-rw-r--r--src/cairo-xlib-xcb-surface.c1
9 files changed, 123 insertions, 47 deletions
diff --git a/boilerplate/cairo-boilerplate-xcb.c b/boilerplate/cairo-boilerplate-xcb.c
index 5ddf3fa8..0a5f5a4f 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 97f8ccef..63eb59df 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 25e821e0..9da4eb3e 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 1c8fc41a..e0669111 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 0c44e4d3..c80bf2d9 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 2a903a07..3fbb0722 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 c108bae2..9c2d4621 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 7b728323..49b2dfbb 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 7e674bf0..84e9e339 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));