[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