xcb: trivial memfault fixes.

The first fixes required to kick-start memfault testing of the xcb
backend.
This commit is contained in:
Chris Wilson 2010-05-10 13:36:53 +01:00
parent 8b486db9a9
commit e540d040bd
9 changed files with 127 additions and 51 deletions

View file

@ -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);

View file

@ -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

View file

@ -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,12 +621,48 @@ _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;
cairo_list_init (&connection->fonts);
cairo_list_init (&connection->screens);
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,
sizeof (cairo_xcb_xid_t));
cairo_list_init (&connection->shm_pools);
_cairo_freepool_init (&connection->shm_info_freelist,
sizeof (cairo_xcb_shm_info_t));
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
@ -639,31 +677,13 @@ _cairo_xcb_connection_get (xcb_connection_t *xcb_connection)
xcb_prefetch_maximum_request_length (xcb_connection);
cairo_list_init (&connection->fonts);
cairo_list_init (&connection->screens);
cairo_list_add (&connection->link, &connections);
connection->xrender_formats = _cairo_hash_table_create (_xrender_formats_equal);
connection->visual_to_xrender_format = _cairo_hash_table_create (_xrender_formats_equal);
cairo_list_init (&connection->free_xids);
_cairo_freepool_init (&connection->xid_pool,
sizeof (cairo_xcb_xid_t));
cairo_list_init (&connection->shm_pools);
_cairo_freepool_init (&connection->shm_info_freelist,
sizeof (cairo_xcb_shm_info_t));
connection->maximum_request_length =
xcb_get_maximum_request_length (xcb_connection);
connection->flags = 0;
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);

View file

@ -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

View file

@ -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;
}

View file

@ -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 *)

View file

@ -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);

View file

@ -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;

View file

@ -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));