mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-03-11 06:00:33 +01:00
xcb: trivial memfault fixes.
The first fixes required to kick-start memfault testing of the xcb backend.
This commit is contained in:
parent
8b486db9a9
commit
e540d040bd
9 changed files with 127 additions and 51 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 *)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue