[PATCH 3/4] xcb: Move the allocation of a shm surface into its own function
Uli Schlachter
psychon at znc.in
Sun Jan 30 06:43:00 PST 2011
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.
Signed-off-by: Uli Schlachter <psychon at znc.in>
---
src/cairo-xcb-surface-core.c | 111 +++++++++++++++++++++++++++--------------
1 files changed, 73 insertions(+), 38 deletions(-)
diff --git a/src/cairo-xcb-surface-core.c b/src/cairo-xcb-surface-core.c
index bcfb7a1..6801e3f 100644
--- a/src/cairo-xcb-surface-core.c
+++ b/src/cairo-xcb-surface-core.c
@@ -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;
-
- 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
+ status = _cairo_xcb_shm_image_create_shm (connection,
+ pixman_format,
+ width,
+ height,
+ image_out,
+ shm_info_out);
- 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;
}
--
1.7.2.3
--------------060000060309050604010504
Content-Type: text/x-diff;
name="0004-xcb-Use-a-normal-image-surface-if-SHM-fails.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="0004-xcb-Use-a-normal-image-surface-if-SHM-fails.patch"
More information about the cairo
mailing list