[cairo-commit] 5 commits - src/cairo-xcb-private.h src/cairo-xcb-shm.c src/cairo-xcb-surface.c src/cairo-xcb-surface-core.c test/Makefile.refs test/Makefile.sources test/xcb-huge-image-shm.c test/xcb-huge-image-shm.ref.png
Uli Schlachter
psychon at kemper.freedesktop.org
Thu Aug 18 07:35:51 PDT 2011
src/cairo-xcb-private.h | 2 +
src/cairo-xcb-shm.c | 11 +++---
src/cairo-xcb-surface-core.c | 3 +
src/cairo-xcb-surface.c | 55 +++++++-------------------------
test/Makefile.refs | 1
test/Makefile.sources | 1
test/xcb-huge-image-shm.c | 67 ++++++++++++++++++++++++++++++++++++++++
test/xcb-huge-image-shm.ref.png |binary
8 files changed, 92 insertions(+), 48 deletions(-)
New commits:
commit 5d92ce3a181c439e0b5a160a5820bf20ccaf5414
Author: Uli Schlachter <psychon at znc.in>
Date: Thu Aug 18 15:37:13 2011 +0200
xcb-shm: Fix a logic error while allocating mem
The "continue;" in the old code never worked, because it first checked the loop
condition. Since "FALSE" (hopefully) never evaluates to true, the loop was still
left.
Signed-off-by: Uli Schlachter <psychon at znc.in>
diff --git a/src/cairo-xcb-shm.c b/src/cairo-xcb-shm.c
index 1d630a7..ffcaec8 100644
--- a/src/cairo-xcb-shm.c
+++ b/src/cairo-xcb-shm.c
@@ -548,11 +548,12 @@ _cairo_xcb_connection_allocate_shm_info (cairo_xcb_connection_t *connection,
if (pool->shmid != -1)
break;
- if (errno == EINVAL && bytes > size) {
- bytes >>= 1;
- continue;
- }
- } while (FALSE);
+ /* If the allocation failed because we asked for too much memory, we try
+ * again with a smaller request, as long as our allocation still fits. */
+ bytes >>= 1;
+ if (errno != EINVAL || bytes < size)
+ break;
+ } while (TRUE);
if (pool->shmid == -1) {
int err = errno;
if (! (err == EINVAL || err == ENOMEM))
commit 73e7391e6e53b894f763f4715590d3be7e7ec243
Author: Uli Schlachter <psychon at znc.in>
Date: Thu Aug 18 15:20:35 2011 +0200
xcb: Handle SHM exhaustion via falling back
When we couldn't get an image from the X11 server via SHM because we ran out
shared memory, we should try again via a normal GetImage request.
Fixes: xcb-huge-image-shm
Signed-off-by: Uli Schlachter <psychon at znc.in>
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index c3df5ed..ebea5ff 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -348,8 +348,13 @@ _get_image (cairo_xcb_surface_t *surface,
if (use_shm) {
image = _get_shm_image (surface, x, y, width, height);
if (image) {
- _cairo_xcb_connection_release (connection);
- return image;
+ /* XXX This only wants to catch SHM exhaustion,
+ * not other allocation failures. */
+ if (image->status != CAIRO_STATUS_NO_MEMORY) {
+ _cairo_xcb_connection_release (connection);
+ return image;
+ }
+ cairo_surface_destroy (image);
}
}
commit aeba5acbad463db3a9eeb44e26a15979d1831472
Author: Uli Schlachter <psychon at znc.in>
Date: Thu Aug 18 15:10:47 2011 +0200
test: Add a test that maps a huge surface
This test currently fails in the xcb backend if xcb-shm is enabled.
Signed-off-by: Uli Schlachter <psychon at znc.in>
diff --git a/test/Makefile.refs b/test/Makefile.refs
index 2d291f0..500fd82 100644
--- a/test/Makefile.refs
+++ b/test/Makefile.refs
@@ -1402,6 +1402,7 @@ REFERENCE_IMAGES = \
world-map-stroke.ref.png \
world-map.image16.ref.png \
world-map.ref.png \
+ xcb-huge-image-shm.ref.png \
xcb-snapshot-assert.ref.png \
xcb-stress-cache.ref.png \
xcb-surface-source.argb32.ref.png \
diff --git a/test/Makefile.sources b/test/Makefile.sources
index a39a201..7001193 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -320,6 +320,7 @@ test_sources = \
user-font-rescale.c \
world-map.c \
white-in-noop.c \
+ xcb-huge-image-shm.c \
xcb-stress-cache.c \
xcb-snapshot-assert.c \
xcomposite-projection.c \
diff --git a/test/xcb-huge-image-shm.c b/test/xcb-huge-image-shm.c
new file mode 100644
index 0000000..269d7f0
--- /dev/null
+++ b/test/xcb-huge-image-shm.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright © 2011 Uli Schlachter
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Uli Schlachter <psychon at znc.in>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 3000
+#define HEIGHT 3000
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ cairo_surface_t *image;
+ cairo_t *cr2;
+
+ /* We use a similar surface to have way smaller ref images */
+ surface = cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ WIDTH, HEIGHT);
+
+ /* First we have to defeat xcb's deferred clear */
+ cr2 = cairo_create (surface);
+ cairo_test_paint_checkered (cr2);
+ cairo_destroy (cr2);
+
+ /* Now we try to map this to an image. This will try to use shared memory
+ * but fail the allocation, because of the huge surface. */
+ image = cairo_surface_map_to_image (surface, NULL);
+ cairo_surface_unmap_image (surface, image);
+
+ /* Finally we make sure that errors aren't lost. */
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_paint (cr);
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (xcb_huge_image_shm,
+ "Force a failed shm allocation when receiving an image",
+ "xcb", /* keywords */
+ NULL, /* requirements */
+ 2, 2,
+ NULL, draw)
diff --git a/test/xcb-huge-image-shm.ref.png b/test/xcb-huge-image-shm.ref.png
new file mode 100644
index 0000000..a0b24c8
Binary files /dev/null and b/test/xcb-huge-image-shm.ref.png differ
commit 8951c51d9e63dc175bc1eff6592833de627bce74
Author: Uli Schlachter <psychon at znc.in>
Date: Thu Aug 18 12:51:28 2011 +0200
xcb: Merge two functions for creating shm images
This merges most of _cairo_xcb_surface_create_similar_image() into
_cairo_xcb_shm_image_create().
These two functions where already doing almost the same thing with only some
differences in error handling.
Signed-off-by: Uli Schlachter <psychon at znc.in>
diff --git a/src/cairo-xcb-private.h b/src/cairo-xcb-private.h
index d9557b4..648bd57 100644
--- a/src/cairo-xcb-private.h
+++ b/src/cairo-xcb-private.h
@@ -56,6 +56,8 @@
#include <xcb/xcbext.h>
#include <pixman.h>
+#define XLIB_COORD_MAX 32767
+
/* maximum number of cached GC's */
#define GC_CACHE_SIZE 4
diff --git a/src/cairo-xcb-surface-core.c b/src/cairo-xcb-surface-core.c
index 0770dcd..20cb5d3 100644
--- a/src/cairo-xcb-surface-core.c
+++ b/src/cairo-xcb-surface-core.c
@@ -156,6 +156,9 @@ _cairo_xcb_shm_image_create_shm (cairo_xcb_connection_t *connection,
if (! (connection->flags & CAIRO_XCB_HAS_SHM))
return CAIRO_INT_STATUS_UNSUPPORTED;
+ if (unlikely (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX))
+ 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)
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index 48aa176..c3df5ed 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -46,8 +46,6 @@
#include "cairo-default-context-private.h"
#include "cairo-image-surface-private.h"
-#define XLIB_COORD_MAX 32767
-
#if CAIRO_HAS_XLIB_XCB_FUNCTIONS
slim_hidden_proto (cairo_xcb_surface_create);
slim_hidden_proto (cairo_xcb_surface_create_for_bitmap);
@@ -164,56 +162,22 @@ _cairo_xcb_surface_create_similar_image (void *abstract_other,
int width,
int height)
{
-#if CAIRO_HAS_XCB_SHM_FUNCTIONS
cairo_xcb_surface_t *other = abstract_other;
cairo_xcb_connection_t *connection = other->connection;
- cairo_surface_t *image;
cairo_xcb_shm_info_t *shm_info;
+ cairo_image_surface_t *image;
cairo_status_t status;
- size_t stride;
pixman_format_code_t pixman_format;
- if (unlikely(width > XLIB_COORD_MAX || height > XLIB_COORD_MAX))
- return cairo_image_surface_create (format, width, height);
-
- if ((connection->flags & CAIRO_XCB_HAS_SHM) == 0)
- return cairo_image_surface_create (format, width, height);
-
pixman_format = _cairo_format_to_pixman_format_code (format);
- stride = CAIRO_STRIDE_FOR_WIDTH_BPP (width,
- PIXMAN_FORMAT_BPP (pixman_format));
- status = _cairo_xcb_connection_allocate_shm_info (connection,
- stride * height,
- &shm_info);
+ status = _cairo_xcb_shm_image_create (connection, pixman_format,
+ width, height, &image,
+ &shm_info);
if (unlikely (status))
- return cairo_image_surface_create (format, width, height);
-
- image = _cairo_image_surface_create_with_pixman_format (shm_info->mem,
- pixman_format,
- width,
- height,
- stride);
- if (unlikely (image->status)) {
- _cairo_xcb_shm_info_destroy (shm_info);
- return image;
- }
-
- 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 _cairo_surface_create_in_error (status);
- }
-
- return image;
-#else
- return cairo_image_surface_create (format, width, height);
-#endif
+ return &image->base;
}
static cairo_status_t
commit 0da3d3efd21e4a8bf1356c0829ac5b0a30f2df88
Author: Uli Schlachter <psychon at znc.in>
Date: Mon Aug 8 22:35:20 2011 +0200
xcb: Fallback to image if allocating SHM fails
This turns an !!!ERROR!!! for scale-offset-similar with xcb-fallback into a
failed test and might fix other problems. However, since the problem here partly
is a race, those other problems might only be hit sometimes.
Signed-off-by: Uli Schlachter <psychon at znc.in>
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index abf8fe3..48aa176 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -188,7 +188,7 @@ _cairo_xcb_surface_create_similar_image (void *abstract_other,
stride * height,
&shm_info);
if (unlikely (status))
- return _cairo_surface_create_in_error (status);
+ return cairo_image_surface_create (format, width, height);
image = _cairo_image_surface_create_with_pixman_format (shm_info->mem,
pixman_format,
More information about the cairo-commit
mailing list