mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-04 08:17:59 +02:00
xcb: Move the allocation of a shm surface into its own function
This simplifies the fallback to an image surface when something causes an error. Additionally, this causes errors from _cairo_xcb_connection_allocate_shm_info to be handled via falling back to a normal image surface while previously those were returned to the caller. Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
48cb9186a2
commit
72788a0660
1 changed files with 73 additions and 38 deletions
|
|
@ -140,6 +140,69 @@ _cairo_xcb_pixmap_copy (cairo_xcb_surface_t *target)
|
|||
return surface;
|
||||
}
|
||||
|
||||
#if CAIRO_HAS_XCB_SHM_FUNCTIONS
|
||||
static cairo_status_t
|
||||
_cairo_xcb_shm_image_create_shm (cairo_xcb_connection_t *connection,
|
||||
pixman_format_code_t pixman_format,
|
||||
int width, int height,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_xcb_shm_info_t **shm_info_out)
|
||||
{
|
||||
cairo_surface_t *image = NULL;
|
||||
cairo_xcb_shm_info_t *shm_info = NULL;
|
||||
cairo_status_t status;
|
||||
size_t size, stride;
|
||||
|
||||
if (! (connection->flags & CAIRO_XCB_HAS_SHM))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
stride = CAIRO_STRIDE_FOR_WIDTH_BPP (width, PIXMAN_FORMAT_BPP (pixman_format));
|
||||
size = stride * height;
|
||||
if (size <= CAIRO_XCB_SHM_SMALL_IMAGE)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
status = _cairo_xcb_connection_allocate_shm_info (connection,
|
||||
size, &shm_info);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
image = _cairo_image_surface_create_with_pixman_format (shm_info->mem,
|
||||
pixman_format,
|
||||
width, height,
|
||||
stride);
|
||||
status = image->status;
|
||||
if (unlikely (status)) {
|
||||
_cairo_xcb_shm_info_destroy (shm_info);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = _cairo_user_data_array_set_data (&image->user_data,
|
||||
(const cairo_user_data_key_t *) connection,
|
||||
shm_info,
|
||||
(cairo_destroy_func_t) _cairo_xcb_shm_info_destroy);
|
||||
|
||||
if (unlikely (status)) {
|
||||
cairo_surface_destroy (image);
|
||||
_cairo_xcb_shm_info_destroy (shm_info);
|
||||
return status;
|
||||
}
|
||||
|
||||
*image_out = (cairo_image_surface_t *) image;
|
||||
*shm_info_out = shm_info;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
#else
|
||||
static cairo_status_t
|
||||
_cairo_xcb_shm_image_create_shm (cairo_xcb_connection_t *connection,
|
||||
pixman_format_code_t pixman_format,
|
||||
int width, int height,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_xcb_shm_info_t **shm_info_out)
|
||||
{
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
cairo_status_t
|
||||
_cairo_xcb_shm_image_create (cairo_xcb_connection_t *connection,
|
||||
pixman_format_code_t pixman_format,
|
||||
|
|
@ -151,42 +214,14 @@ _cairo_xcb_shm_image_create (cairo_xcb_connection_t *connection,
|
|||
cairo_xcb_shm_info_t *shm_info = NULL;
|
||||
cairo_status_t status;
|
||||
|
||||
#if CAIRO_HAS_XCB_SHM_FUNCTIONS
|
||||
if ((connection->flags & CAIRO_XCB_HAS_SHM)) {
|
||||
size_t size, stride;
|
||||
status = _cairo_xcb_shm_image_create_shm (connection,
|
||||
pixman_format,
|
||||
width,
|
||||
height,
|
||||
image_out,
|
||||
shm_info_out);
|
||||
|
||||
stride = CAIRO_STRIDE_FOR_WIDTH_BPP (width, PIXMAN_FORMAT_BPP (pixman_format));
|
||||
size = stride * height;
|
||||
if (size > CAIRO_XCB_SHM_SMALL_IMAGE) {
|
||||
status = _cairo_xcb_connection_allocate_shm_info (connection,
|
||||
size, &shm_info);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
image = _cairo_image_surface_create_with_pixman_format (shm_info->mem,
|
||||
pixman_format,
|
||||
width, height,
|
||||
stride);
|
||||
status = image->status;
|
||||
if (unlikely (status)) {
|
||||
_cairo_xcb_shm_info_destroy (shm_info);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = _cairo_user_data_array_set_data (&image->user_data,
|
||||
(const cairo_user_data_key_t *) connection,
|
||||
shm_info,
|
||||
(cairo_destroy_func_t) _cairo_xcb_shm_info_destroy);
|
||||
if (unlikely (status)) {
|
||||
cairo_surface_destroy (image);
|
||||
_cairo_xcb_shm_info_destroy (shm_info);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (image == NULL) {
|
||||
if (status != CAIRO_STATUS_SUCCESS) {
|
||||
image = _cairo_image_surface_create_with_pixman_format (NULL,
|
||||
pixman_format,
|
||||
width, height,
|
||||
|
|
@ -194,11 +229,11 @@ _cairo_xcb_shm_image_create (cairo_xcb_connection_t *connection,
|
|||
status = image->status;
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
*image_out = (cairo_image_surface_t *) image;
|
||||
*shm_info_out = shm_info;
|
||||
}
|
||||
|
||||
|
||||
*image_out = (cairo_image_surface_t *) image;
|
||||
*shm_info_out = shm_info;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue