diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2008-08-11 21:12:45 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2008-08-13 21:54:59 +0100 |
commit | 436c0c8be28546813139f391a62303d4c1894fc3 (patch) | |
tree | 7134b42ba4af4da886f8bd7906f4d6a144d1a134 /boilerplate | |
parent | c73b3e43e120065e40d8fc48c9bdbd88ebe8ab40 (diff) |
[test] Preparatory work for running under memfault.
In order to run under memfault, the framework is first extended to handle
running concurrent tests - i.e. multi-threading. (Not that this is a
requirement for memfault, instead it shares a common goal of storing
per-test data). To that end all the global data is moved into a per-test
context and the targets are adjusted to avoid overlap on shared, global
resources (such as output files and frame buffers). In order to preserve
the simplicity of the standard draw routines, the context is not passed
explicitly as a parameter to the routines, but is instead attached to the
cairo_t via the user_data.
For the masochist, to enable the tests to be run across multiple threads
simply set the environment variable CAIRO_TEST_NUM_THREADS to the desired
number.
In the long run, we can hope the need for memfault (runtime testing of
error paths) will be mitigated by static analysis. A promising candidate
for this task would appear to be http://hal.cs.berkeley.edu/cil/.
Diffstat (limited to 'boilerplate')
25 files changed, 338 insertions, 111 deletions
diff --git a/boilerplate/cairo-boilerplate-beos-private.h b/boilerplate/cairo-boilerplate-beos-private.h index b572353b..1d800c26 100644 --- a/boilerplate/cairo-boilerplate-beos-private.h +++ b/boilerplate/cairo-boilerplate-beos-private.h @@ -12,7 +12,10 @@ _cairo_boilerplate_beos_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure); extern void @@ -23,7 +26,10 @@ _cairo_boilerplate_beos_create_surface_for_bitmap (const char *name cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure); extern void diff --git a/boilerplate/cairo-boilerplate-directfb-private.h b/boilerplate/cairo-boilerplate-directfb-private.h index c8c936d6..87d1b8b0 100644 --- a/boilerplate/cairo-boilerplate-directfb-private.h +++ b/boilerplate/cairo-boilerplate-directfb-private.h @@ -12,7 +12,10 @@ _cairo_boilerplate_directfb_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure); extern void diff --git a/boilerplate/cairo-boilerplate-directfb.c b/boilerplate/cairo-boilerplate-directfb.c index d6d616b1..5a127555 100644 --- a/boilerplate/cairo-boilerplate-directfb.c +++ b/boilerplate/cairo-boilerplate-directfb.c @@ -43,7 +43,7 @@ static DFBInfo *init(void) { DFBDisplayLayerConfig layer_config; DFBGraphicsDeviceDescription desc; int err; - DFBInfo *info = calloc(1,sizeof(DFBInfo)); + DFBInfo *info = xcalloc(1,sizeof(DFBInfo)); if( !info ) return NULL; @@ -142,7 +142,10 @@ _cairo_boilerplate_directfb_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure) { diff --git a/boilerplate/cairo-boilerplate-getopt.c b/boilerplate/cairo-boilerplate-getopt.c index be66ac23..775d1efe 100644 --- a/boilerplate/cairo-boilerplate-getopt.c +++ b/boilerplate/cairo-boilerplate-getopt.c @@ -40,9 +40,6 @@ #include "cairo-boilerplate-getopt.h" -static const char* ID = "$Id: getopt.c,v 1.2 2003/10/26 03:10:20 vindaci Exp $"; - - char* optarg = NULL; int optind = 0; int opterr = 1; @@ -57,7 +54,7 @@ static int opt_offset = 0; /* Index into compounded "-option" */ static int dashdash = 0; /* True if "--" option reached */ static int nonopt = 0; /* How many nonopts we've found */ -static void increment_index() +static void increment_index(void) { /* Move onto the next option */ if(argv_index < argv_index2) @@ -74,7 +71,7 @@ static void increment_index() * Permutes argv[] so that the argument currently being processed is moved * to the end. */ -static int permute_argv_once() +static int permute_argv_once(void) { /* Movability check */ if(argv_index + nonopt >= prev_argc) return 1; diff --git a/boilerplate/cairo-boilerplate-glitz-private.h b/boilerplate/cairo-boilerplate-glitz-private.h index e2b27fd2..faeeb630 100644 --- a/boilerplate/cairo-boilerplate-glitz-private.h +++ b/boilerplate/cairo-boilerplate-glitz-private.h @@ -37,7 +37,10 @@ _cairo_boilerplate_glitz_glx_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure); void @@ -50,7 +53,10 @@ _cairo_boilerplate_glitz_agl_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure); void @@ -63,7 +69,10 @@ _cairo_boilerplate_glitz_wgl_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure); void diff --git a/boilerplate/cairo-boilerplate-glitz.c b/boilerplate/cairo-boilerplate-glitz.c index 9ef7115d..b0d65acd 100644 --- a/boilerplate/cairo-boilerplate-glitz.c +++ b/boilerplate/cairo-boilerplate-glitz.c @@ -148,6 +148,7 @@ _cairo_boilerplate_glitz_glx_create_surface_internal (glitz_format_name_t form glitz_drawable_destroy (drawable); return sr; + DESTROY_DRAWABLE: glitz_drawable_destroy (drawable); DESTROY_WINDOW: @@ -162,12 +163,16 @@ _cairo_boilerplate_glitz_glx_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure) { glitz_glx_target_closure_t *gxtc; glitz_surface_t * glitz_surface; - cairo_surface_t * surface; + cairo_surface_t * surface = NULL; + cairo_status_t status; *closure = gxtc = xmalloc (sizeof (glitz_glx_target_closure_t)); @@ -204,19 +209,28 @@ _cairo_boilerplate_glitz_glx_create_surface (const char *name, } surface = cairo_glitz_surface_create (glitz_surface); + glitz_surface_destroy (glitz_surface); + + if (cairo_surface_status (surface)) + goto FAIL_CLOSE_DISPLAY; gxtc->base.width = width; gxtc->base.height = height; gxtc->base.content = content; - cairo_surface_set_user_data (surface, &glitz_closure_key, - gxtc, NULL); + status = cairo_boilerplate_surface_set_user_data (surface, + &glitz_closure_key, gxtc, NULL); + if (status == CAIRO_STATUS_SUCCESS) + return surface; - return surface; + cairo_surface_destroy (surface); + surface = cairo_boilerplate_surface_create_in_error (status); FAIL_CLOSE_DISPLAY: + glitz_glx_fini (); XCloseDisplay (gxtc->dpy); FAIL: - return NULL; + free (gxtc); + return surface; } void @@ -298,9 +312,10 @@ _cairo_boilerplate_glitz_agl_create_surface_internal (glitz_format_name_t form DESTROY_DRAWABLE: glitz_drawable_destroy (gdraw); + return sr; FAIL: - return sr; /* will be NULL unless we create it and attach */ + return NULL; } cairo_surface_t * @@ -308,11 +323,14 @@ _cairo_boilerplate_glitz_agl_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure) { glitz_surface_t *glitz_surface; - cairo_surface_t *surface; + cairo_surface_t *surface = NULL; glitz_agl_target_closure_t *aglc; glitz_agl_init (); @@ -335,16 +353,25 @@ _cairo_boilerplate_glitz_agl_create_surface (const char *name, goto FAIL; surface = cairo_glitz_surface_create (glitz_surface); + glitz_surface_destroy (glitz_surface); + + if (cairo_surface_status (surface)) + goto FAIL; aglc->base.width = width; aglc->base.height = height; aglc->base.content = content; - cairo_surface_set_user_data (surface, &glitz_closure_key, aglc, NULL); + status = cairo_boilerplate_surface_set_user_data (surface, + &glitz_closure_key, aglc, NULL); + if (status == CAIRO_STATUS_SUCCESS) + return surface; - return surface; + cairo_surface_destroy (surface); + surface = cairo_boilerplate_surface_create_in_error (status); FAIL: - return NULL; + glitz_agl_fini (); + return surface; } void @@ -428,11 +455,14 @@ _cairo_boilerplate_glitz_wgl_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure) { glitz_surface_t *glitz_surface; - cairo_surface_t *surface; + cairo_surface_t *surface = NULL; glitz_wgl_target_closure_t *wglc; glitz_wgl_init (NULL); @@ -455,16 +485,26 @@ _cairo_boilerplate_glitz_wgl_create_surface (const char *name, goto FAIL; surface = cairo_glitz_surface_create (glitz_surface); + glitz_surface_destroy (glitz_surface); + + if (cairo_surface_status (surface)) + goto FAIL; wglc->base.width = width; wglc->base.height = height; wglc->base.content = content; - cairo_surface_set_user_data (surface, &glitz_closure_key, wglc, NULL); + status = cairo_boilerplate_surface_set_user_data (surface, + &glitz_closure_key, wglc, NULL); + if (status == CAIRO_STATUS_SUCCESS) + return surface; - return surface; + cairo_surface_destroy (surface); + surface = cairo_boilerplate_surface_create_in_error (status); FAIL: - return NULL; + glitz_wgl_fini (); + free (wglc); + return surface; } void diff --git a/boilerplate/cairo-boilerplate-pdf-private.h b/boilerplate/cairo-boilerplate-pdf-private.h index 7ce181e0..a792cc40 100644 --- a/boilerplate/cairo-boilerplate-pdf-private.h +++ b/boilerplate/cairo-boilerplate-pdf-private.h @@ -32,7 +32,10 @@ _cairo_boilerplate_pdf_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure); void diff --git a/boilerplate/cairo-boilerplate-pdf.c b/boilerplate/cairo-boilerplate-pdf.c index cc26d91b..8eedd9d9 100644 --- a/boilerplate/cairo-boilerplate-pdf.c +++ b/boilerplate/cairo-boilerplate-pdf.c @@ -49,11 +49,15 @@ _cairo_boilerplate_pdf_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure) { pdf_target_closure_t *ptc; cairo_surface_t *surface; + cairo_status_t status; /* Sanitize back to a real cairo_content_t value. */ if (content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED) @@ -64,15 +68,13 @@ _cairo_boilerplate_pdf_create_surface (const char *name, ptc->width = width; ptc->height = height; - xasprintf (&ptc->filename, "%s-pdf-%s-out.pdf", - name, cairo_boilerplate_content_name (content)); + xasprintf (&ptc->filename, "%s-pdf-%s-%d-out.pdf", + name, cairo_boilerplate_content_name (content), id); surface = cairo_pdf_surface_create (ptc->filename, width, height); - if (cairo_surface_status (surface)) { - free (ptc->filename); - free (ptc); - return NULL; - } + if (cairo_surface_status (surface)) + goto CLEANUP_FILENAME; + cairo_surface_set_fallback_resolution (surface, 72., 72.); if (content == CAIRO_CONTENT_COLOR) { @@ -80,14 +82,24 @@ _cairo_boilerplate_pdf_create_surface (const char *name, surface = cairo_surface_create_similar (ptc->target, CAIRO_CONTENT_COLOR, width, height); + if (cairo_surface_status (surface)) + goto CLEANUP_TARGET; } else { ptc->target = NULL; } - cairo_boilerplate_surface_set_user_data (surface, - &pdf_closure_key, - ptc, NULL); + status = cairo_surface_set_user_data (surface, &pdf_closure_key, ptc, NULL); + if (status == CAIRO_STATUS_SUCCESS) + return surface; + cairo_surface_destroy (surface); + surface = cairo_boilerplate_surface_create_in_error (status); + + CLEANUP_TARGET: + cairo_surface_destroy (ptc->target); + CLEANUP_FILENAME: + free (ptc->filename); + free (ptc); return surface; } @@ -96,6 +108,7 @@ _cairo_boilerplate_pdf_surface_write_to_png (cairo_surface_t *surface, const cha { pdf_target_closure_t *ptc = cairo_surface_get_user_data (surface, &pdf_closure_key); char command[4096]; + cairo_status_t status; /* Both surface and ptc->target were originally created at the * same dimensions. We want a 1:1 copy here, so we first clear any @@ -112,13 +125,25 @@ _cairo_boilerplate_pdf_surface_write_to_png (cairo_surface_t *surface, const cha cairo_set_source_surface (cr, surface, 0, 0); cairo_paint (cr); cairo_show_page (cr); + status = cairo_status (cr); cairo_destroy (cr); + if (status) + return status; + cairo_surface_finish (surface); + status = cairo_surface_status (surface); + if (status) + return status; + surface = ptc->target; } cairo_surface_finish (surface); + status = cairo_surface_status (surface); + if (status) + return status; + sprintf (command, "./pdf2png %s %s 1", ptc->filename, filename); diff --git a/boilerplate/cairo-boilerplate-ps-private.h b/boilerplate/cairo-boilerplate-ps-private.h index 8d1faf1f..07b15f69 100644 --- a/boilerplate/cairo-boilerplate-ps-private.h +++ b/boilerplate/cairo-boilerplate-ps-private.h @@ -32,7 +32,10 @@ _cairo_boilerplate_ps_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure); void diff --git a/boilerplate/cairo-boilerplate-ps.c b/boilerplate/cairo-boilerplate-ps.c index 7d5ea7d4..08580cd1 100644 --- a/boilerplate/cairo-boilerplate-ps.c +++ b/boilerplate/cairo-boilerplate-ps.c @@ -47,11 +47,15 @@ _cairo_boilerplate_ps_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure) { ps_target_closure_t *ptc; cairo_surface_t *surface; + cairo_status_t status; /* Sanitize back to a real cairo_content_t value. */ if (content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED) @@ -59,18 +63,16 @@ _cairo_boilerplate_ps_create_surface (const char *name, *closure = ptc = xmalloc (sizeof (ps_target_closure_t)); - xasprintf (&ptc->filename, "%s-ps-%s-out.ps", - name, cairo_boilerplate_content_name (content)); + xasprintf (&ptc->filename, "%s-ps-%s-%d-out.ps", + name, cairo_boilerplate_content_name (content), id); ptc->width = width; ptc->height = height; surface = cairo_ps_surface_create (ptc->filename, width, height); - if (cairo_surface_status (surface)) { - free (ptc->filename); - free (ptc); - return NULL; - } + if (cairo_surface_status (surface)) + goto CLEANUP_FILENAME; + cairo_surface_set_fallback_resolution (surface, 72., 72.); if (content == CAIRO_CONTENT_COLOR) { @@ -78,22 +80,24 @@ _cairo_boilerplate_ps_create_surface (const char *name, surface = cairo_surface_create_similar (ptc->target, CAIRO_CONTENT_COLOR, width, height); + if (cairo_surface_status (surface)) + goto CLEANUP_TARGET; } else { ptc->target = NULL; } - if (cairo_surface_set_user_data (surface, - &ps_closure_key, - ptc, - NULL) != CAIRO_STATUS_SUCCESS) { - cairo_surface_destroy (surface); - if (ptc->target != NULL) - cairo_surface_destroy (ptc->target); - free (ptc->filename); - free (ptc); - return NULL; - } + status = cairo_surface_set_user_data (surface, &ps_closure_key, ptc, NULL); + if (status == CAIRO_STATUS_SUCCESS) + return surface; + cairo_surface_destroy (surface); + surface = cairo_boilerplate_surface_create_in_error (status); + + CLEANUP_TARGET: + cairo_surface_destroy (ptc->target); + CLEANUP_FILENAME: + free (ptc->filename); + free (ptc); return surface; } @@ -102,6 +106,7 @@ _cairo_boilerplate_ps_surface_write_to_png (cairo_surface_t *surface, const char { ps_target_closure_t *ptc = cairo_surface_get_user_data (surface, &ps_closure_key); char command[4096]; + cairo_status_t status; /* Both surface and ptc->target were originally created at the * same dimensions. We want a 1:1 copy here, so we first clear any @@ -118,17 +123,30 @@ _cairo_boilerplate_ps_surface_write_to_png (cairo_surface_t *surface, const char cairo_set_source_surface (cr, surface, 0, 0); cairo_paint (cr); cairo_show_page (cr); + status = cairo_status (cr); cairo_destroy (cr); + if (status) + return status; + cairo_surface_finish (surface); + status = cairo_surface_status (surface); + if (status) + return status; + surface = ptc->target; } cairo_surface_finish (surface); + status = cairo_surface_status (surface); + if (status) + return status; + sprintf (command, "gs -q -r72 -g%dx%d -dSAFER -dBATCH -dNOPAUSE -sDEVICE=pngalpha -sOutputFile=%s %s", ptc->width, ptc->height, filename, ptc->filename); if (system (command) == 0) return CAIRO_STATUS_SUCCESS; + return CAIRO_STATUS_WRITE_ERROR; } diff --git a/boilerplate/cairo-boilerplate-quartz-private.h b/boilerplate/cairo-boilerplate-quartz-private.h index 808342f5..573e247e 100644 --- a/boilerplate/cairo-boilerplate-quartz-private.h +++ b/boilerplate/cairo-boilerplate-quartz-private.h @@ -28,12 +28,15 @@ #define _CAIRO_BOILERPLATE_QUARTZ_PRIVATE_H_ cairo_surface_t * -_cairo_boilerplate_quartz_create_surface (const char *name, - cairo_content_t content, - int width, - int height, +_cairo_boilerplate_quartz_create_surface (const char *name, + cairo_content_t content, + int width, + int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, - void **closure); + int id, + void **closure); void _cairo_boilerplate_quartz_cleanup (void *closure); diff --git a/boilerplate/cairo-boilerplate-quartz.c b/boilerplate/cairo-boilerplate-quartz.c index 3b23aed2..30652131 100644 --- a/boilerplate/cairo-boilerplate-quartz.c +++ b/boilerplate/cairo-boilerplate-quartz.c @@ -34,7 +34,10 @@ _cairo_boilerplate_quartz_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure) { cairo_format_t format; diff --git a/boilerplate/cairo-boilerplate-svg-private.h b/boilerplate/cairo-boilerplate-svg-private.h index ffc56c8a..4cf5f632 100644 --- a/boilerplate/cairo-boilerplate-svg-private.h +++ b/boilerplate/cairo-boilerplate-svg-private.h @@ -32,7 +32,10 @@ _cairo_boilerplate_svg_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure); void diff --git a/boilerplate/cairo-boilerplate-svg.c b/boilerplate/cairo-boilerplate-svg.c index b85a95e8..db7e6656 100644 --- a/boilerplate/cairo-boilerplate-svg.c +++ b/boilerplate/cairo-boilerplate-svg.c @@ -46,26 +46,28 @@ _cairo_boilerplate_svg_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure) { svg_target_closure_t *ptc; cairo_surface_t *surface; + cairo_status_t status; *closure = ptc = xmalloc (sizeof (svg_target_closure_t)); ptc->width = width; ptc->height = height; - xasprintf (&ptc->filename, "%s-svg-%s-out.svg", - name, cairo_boilerplate_content_name (content)); + xasprintf (&ptc->filename, "%s-svg-%s-%d-out.svg", + name, cairo_boilerplate_content_name (content), id); surface = cairo_svg_surface_create (ptc->filename, width, height); - if (cairo_surface_status (surface)) { - free (ptc->filename); - free (ptc); - return NULL; - } + if (cairo_surface_status (surface)) + goto CLEANUP_FILENAME; + cairo_surface_set_fallback_resolution (surface, 72., 72.); if (content == CAIRO_CONTENT_COLOR) { @@ -73,14 +75,24 @@ _cairo_boilerplate_svg_create_surface (const char *name, surface = cairo_surface_create_similar (ptc->target, CAIRO_CONTENT_COLOR, width, height); + if (cairo_surface_status (surface)) + goto CLEANUP_TARGET; } else { ptc->target = NULL; } - cairo_boilerplate_surface_set_user_data (surface, - &svg_closure_key, - ptc, NULL); + status = cairo_surface_set_user_data (surface, &svg_closure_key, ptc, NULL); + if (status == CAIRO_STATUS_SUCCESS) + return surface; + cairo_surface_destroy (surface); + surface = cairo_boilerplate_surface_create_in_error (status); + + CLEANUP_TARGET: + cairo_surface_destroy (ptc->target); + CLEANUP_FILENAME: + free (ptc->filename); + free (ptc); return surface; } @@ -89,6 +101,7 @@ _cairo_boilerplate_svg_surface_write_to_png (cairo_surface_t *surface, const cha { svg_target_closure_t *ptc = cairo_surface_get_user_data (surface, &svg_closure_key); char command[4096]; + cairo_status_t status; /* Both surface and ptc->target were originally created at the * same dimensions. We want a 1:1 copy here, so we first clear any @@ -105,13 +118,25 @@ _cairo_boilerplate_svg_surface_write_to_png (cairo_surface_t *surface, const cha cairo_set_source_surface (cr, surface, 0, 0); cairo_paint (cr); cairo_show_page (cr); + status = cairo_status (cr); cairo_destroy (cr); + if (status) + return status; + cairo_surface_finish (surface); + status = cairo_surface_status (surface); + if (status) + return status; + surface = ptc->target; } cairo_surface_finish (surface); + status = cairo_surface_status (surface); + if (status) + return status; + sprintf (command, "./svg2png %s %s", ptc->filename, filename); diff --git a/boilerplate/cairo-boilerplate-test-surfaces-private.h b/boilerplate/cairo-boilerplate-test-surfaces-private.h index 1b822261..0b2bebcb 100644 --- a/boilerplate/cairo-boilerplate-test-surfaces-private.h +++ b/boilerplate/cairo-boilerplate-test-surfaces-private.h @@ -32,7 +32,10 @@ _cairo_boilerplate_test_fallback_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure); @@ -41,7 +44,10 @@ _cairo_boilerplate_test_meta_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure); @@ -50,7 +56,10 @@ _cairo_boilerplate_test_paginated_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure); cairo_status_t diff --git a/boilerplate/cairo-boilerplate-test-surfaces.c b/boilerplate/cairo-boilerplate-test-surfaces.c index e112dca6..f38dda95 100644 --- a/boilerplate/cairo-boilerplate-test-surfaces.c +++ b/boilerplate/cairo-boilerplate-test-surfaces.c @@ -38,7 +38,10 @@ _cairo_boilerplate_test_fallback_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure) { *closure = NULL; @@ -50,7 +53,10 @@ _cairo_boilerplate_test_meta_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure) { *closure = NULL; @@ -72,11 +78,15 @@ _cairo_boilerplate_test_paginated_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure) { test_paginated_closure_t *tpc; cairo_surface_t *surface; + cairo_status_t status; *closure = tpc = xmalloc (sizeof (test_paginated_closure_t)); @@ -92,11 +102,21 @@ _cairo_boilerplate_test_paginated_create_surface (const char *name, tpc->width, tpc->height, tpc->stride); + if (cairo_surface_status (surface)) + goto CLEANUP; + + status = cairo_surface_set_user_data (surface, + &test_paginated_closure_key, + tpc, NULL); + if (status == CAIRO_STATUS_SUCCESS) + return surface; - cairo_boilerplate_surface_set_user_data (surface, - &test_paginated_closure_key, - tpc, NULL); + cairo_surface_destroy (surface); + surface = cairo_boilerplate_surface_create_in_error (status); + CLEANUP: + free (tpc->data); + free (tpc); return surface; } @@ -137,16 +157,9 @@ _cairo_boilerplate_test_paginated_surface_write_to_png (cairo_surface_t *surface tpc->stride); status = cairo_surface_write_to_png (image, filename); - if (status) { - CAIRO_BOILERPLATE_LOG ("Error writing %s: %s. Exiting\n", - filename, - cairo_status_to_string (status)); - exit (1); - } - cairo_surface_destroy (image); - return CAIRO_STATUS_SUCCESS; + return status; } void diff --git a/boilerplate/cairo-boilerplate-win32-private.h b/boilerplate/cairo-boilerplate-win32-private.h index e5ef0f6c..26f4b621 100644 --- a/boilerplate/cairo-boilerplate-win32-private.h +++ b/boilerplate/cairo-boilerplate-win32-private.h @@ -32,7 +32,10 @@ _cairo_boilerplate_win32_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure); cairo_surface_t * diff --git a/boilerplate/cairo-boilerplate-win32.c b/boilerplate/cairo-boilerplate-win32.c index cd15873a..4b54a54e 100644 --- a/boilerplate/cairo-boilerplate-win32.c +++ b/boilerplate/cairo-boilerplate-win32.c @@ -34,7 +34,10 @@ _cairo_boilerplate_win32_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure) { cairo_format_t format; diff --git a/boilerplate/cairo-boilerplate-xcb-private.h b/boilerplate/cairo-boilerplate-xcb-private.h index 80717e98..998e6b9c 100644 --- a/boilerplate/cairo-boilerplate-xcb-private.h +++ b/boilerplate/cairo-boilerplate-xcb-private.h @@ -32,7 +32,10 @@ _cairo_boilerplate_xcb_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure); void diff --git a/boilerplate/cairo-boilerplate-xcb.c b/boilerplate/cairo-boilerplate-xcb.c index 1a74d18b..dca7acf9 100644 --- a/boilerplate/cairo-boilerplate-xcb.c +++ b/boilerplate/cairo-boilerplate-xcb.c @@ -52,12 +52,14 @@ _cairo_boilerplate_xcb_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure) { xcb_screen_t *root; xcb_target_closure_t *xtc; - cairo_surface_t *surface; xcb_connection_t *c; xcb_render_pictforminfo_t *render_format; xcb_pict_standard_t format; @@ -97,11 +99,10 @@ _cairo_boilerplate_xcb_create_surface (const char *name, render_format = xcb_render_util_find_standard_format (xcb_render_util_query_formats (c), format); if (render_format->id == 0) return NULL; - surface = cairo_xcb_surface_create_with_xrender_format (c, xtc->pixmap, root, - render_format, - width, height); - return surface; + return cairo_xcb_surface_create_with_xrender_format (c, xtc->pixmap, root, + render_format, + width, height); } void diff --git a/boilerplate/cairo-boilerplate-xlib-private.h b/boilerplate/cairo-boilerplate-xlib-private.h index 54c631cc..0bd911dd 100644 --- a/boilerplate/cairo-boilerplate-xlib-private.h +++ b/boilerplate/cairo-boilerplate-xlib-private.h @@ -33,7 +33,10 @@ _cairo_boilerplate_xlib_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure); #endif @@ -42,7 +45,10 @@ _cairo_boilerplate_xlib_fallback_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure); void diff --git a/boilerplate/cairo-boilerplate-xlib.c b/boilerplate/cairo-boilerplate-xlib.c index 93000d04..250b23f3 100644 --- a/boilerplate/cairo-boilerplate-xlib.c +++ b/boilerplate/cairo-boilerplate-xlib.c @@ -190,13 +190,17 @@ _cairo_boilerplate_xlib_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure) { xlib_target_closure_t *xtc; Display *dpy; + cairo_surface_t *surface; - *closure = xtc = xmalloc (sizeof (xlib_target_closure_t)); + *closure = xtc = xcalloc (1, sizeof (xlib_target_closure_t)); if (width == 0) width = 1; @@ -205,14 +209,20 @@ _cairo_boilerplate_xlib_create_surface (const char *name, xtc->dpy = dpy = XOpenDisplay (NULL); if (xtc->dpy == NULL) { + free (xtc); CAIRO_BOILERPLATE_LOG ("Failed to open display: %s\n", XDisplayName(0)); return NULL; } if (mode == CAIRO_BOILERPLATE_MODE_TEST) - return _cairo_boilerplate_xlib_test_create_surface (dpy, content, width, height, xtc); + surface = _cairo_boilerplate_xlib_test_create_surface (dpy, content, width, height, xtc); else /* mode == CAIRO_BOILERPLATE_MODE_PERF */ - return _cairo_boilerplate_xlib_perf_create_surface (dpy, content, width, height, xtc); + surface = _cairo_boilerplate_xlib_perf_create_surface (dpy, content, width, height, xtc); + + if (surface == NULL || cairo_surface_status (surface)) + _cairo_boilerplate_xlib_cleanup (xtc); + + return surface; } #endif @@ -230,12 +240,16 @@ _cairo_boilerplate_xlib_fallback_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure) { xlib_target_closure_t *xtc; Display *dpy; - int screen; + Screen *scr; + int screen, x, y; XSetWindowAttributes attr; cairo_surface_t *surface; @@ -277,9 +291,25 @@ _cairo_boilerplate_xlib_fallback_create_surface (const char *name, return NULL; } + /* tile the windows so threads do not overlap */ + scr = XScreenOfDisplay (dpy, screen); + x = y = 0; + if (id-- > 1) do { + x += max_width; + if (x + max_width > WidthOfScreen (scr)) { + x = 0; + y += max_height; + if (y + max_height > HeightOfScreen (scr)) { + XCloseDisplay (dpy); + free (xtc); + return NULL; + } + } + } while (--id); + attr.override_redirect = True; xtc->drawable = XCreateWindow (dpy, DefaultRootWindow (dpy), - 0, 0, + x, y, width, height, 0, DefaultDepth (dpy, screen), InputOutput, @@ -304,10 +334,12 @@ _cairo_boilerplate_xlib_cleanup (void *closure) { xlib_target_closure_t *xtc = closure; - if (xtc->drawable_is_pixmap) - XFreePixmap (xtc->dpy, xtc->drawable); - else - XDestroyWindow (xtc->dpy, xtc->drawable); + if (xtc->drawable) { + if (xtc->drawable_is_pixmap) + XFreePixmap (xtc->dpy, xtc->drawable); + else + XDestroyWindow (xtc->dpy, xtc->drawable); + } XCloseDisplay (xtc->dpy); free (xtc); } diff --git a/boilerplate/cairo-boilerplate.c b/boilerplate/cairo-boilerplate.c index f563b7ae..72e0930a 100644 --- a/boilerplate/cairo-boilerplate.c +++ b/boilerplate/cairo-boilerplate.c @@ -118,10 +118,14 @@ _cairo_boilerplate_image_create_surface (const char *name, cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure) { cairo_format_t format; + *closure = NULL; if (content == CAIRO_CONTENT_COLOR_ALPHA) { @@ -448,22 +452,29 @@ cairo_boilerplate_free_targets (cairo_boilerplate_target_t **targets) free (targets); } -void -cairo_boilerplate_surface_set_user_data (cairo_surface_t *surface, - const cairo_user_data_key_t *key, - void *user_data, - cairo_destroy_func_t destroy) +cairo_surface_t * +cairo_boilerplate_surface_create_in_error (cairo_status_t status) { - cairo_status_t status; - - status = cairo_surface_set_user_data (surface, - key, user_data, - destroy); - if (status) { - CAIRO_BOILERPLATE_LOG ("Error: %s. Exiting\n", - cairo_status_to_string (status)); - exit (1); - } + cairo_surface_t *surface = NULL; + + do { + cairo_surface_t *intermediate; + cairo_t *cr; + cairo_path_t path; + + intermediate = cairo_image_surface_create (CAIRO_FORMAT_A8, 0, 0); + cr = cairo_create (intermediate); + cairo_surface_destroy (intermediate); + + path.status = status; + cairo_append_path (cr, &path); + + cairo_surface_destroy (surface); + surface = cairo_get_target (cr); + cairo_destroy (cr); + } while (cairo_surface_status (surface) != status); + + return surface; } void diff --git a/boilerplate/cairo-boilerplate.h b/boilerplate/cairo-boilerplate.h index 8efc6097..8031df8e 100644 --- a/boilerplate/cairo-boilerplate.h +++ b/boilerplate/cairo-boilerplate.h @@ -114,7 +114,10 @@ typedef cairo_surface_t * cairo_content_t content, int width, int height, + int max_width, + int max_height, cairo_boilerplate_mode_t mode, + int id, void **closure); typedef cairo_status_t @@ -137,7 +140,6 @@ typedef struct _cairo_boilerplate_target cairo_boilerplate_cleanup_t cleanup; cairo_boilerplate_wait_t synchronize; cairo_bool_t is_vector; - void *closure; } cairo_boilerplate_target_t; cairo_boilerplate_target_t ** @@ -146,11 +148,8 @@ cairo_boilerplate_get_targets (int *num_targets, cairo_bool_t *limited_targets); void cairo_boilerplate_free_targets (cairo_boilerplate_target_t **targets); -void -cairo_boilerplate_surface_set_user_data (cairo_surface_t *surface, - const cairo_user_data_key_t *key, - void *user_data, - cairo_destroy_func_t destroy); +cairo_surface_t * +cairo_boilerplate_surface_create_in_error (cairo_status_t status); #include "xmalloc.h" diff --git a/boilerplate/xmalloc.c b/boilerplate/xmalloc.c index dfd49463..0a8eeb22 100644 --- a/boilerplate/xmalloc.c +++ b/boilerplate/xmalloc.c @@ -35,8 +35,11 @@ xmalloc (size_t size) { void *buf; + if (size == 0) + return NULL; + buf = malloc (size); - if (buf == NULL && size != 0) { + if (buf == NULL) { CAIRO_BOILERPLATE_LOG ("Error: Out of memory. Exiting.\n"); exit (1); } @@ -49,8 +52,11 @@ xcalloc (size_t nmemb, size_t size) { void *buf; + if (nmemb == 0 || size == 0) + return NULL; + buf = calloc (nmemb, size); - if (buf == NULL && nmemb != 0 && size != 0) { + if (buf == NULL) { CAIRO_BOILERPLATE_LOG ("Error: Out of memory. Exiting\n"); exit (1); } |