[test] Experiment with reference targets

Specify another boilerplate target to use as the reference for this
target. We then use this in cairo-test-trace in preference to using the
image surface. Still not perfect, though the framework is improving.
This commit is contained in:
Chris Wilson 2009-06-19 18:40:43 +01:00
parent cec8579348
commit 0a34abace7
4 changed files with 341 additions and 153 deletions

View file

@ -279,86 +279,86 @@ static const cairo_boilerplate_target_t targets[] =
* for tolerance. There shouldn't ever be anything that is out of
* our control here. */
{
"image", "image", NULL,
"image", "image", NULL, NULL,
CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR_ALPHA, 0,
_cairo_boilerplate_image_create_surface, NULL,
NULL,
_cairo_boilerplate_image_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png
},
{
"image", "image", NULL,
"image", "image", NULL, NULL,
CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR, 0,
_cairo_boilerplate_image_create_surface, NULL,
NULL,
_cairo_boilerplate_image_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png
},
#ifdef CAIRO_HAS_TEST_SURFACES
{
"test-fallback", "image", NULL,
"test-fallback", "image", NULL, NULL,
CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
CAIRO_CONTENT_COLOR_ALPHA, 0,
_cairo_boilerplate_test_fallback_create_surface, NULL,
NULL,
_cairo_boilerplate_test_fallback_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png
},
{
"test-fallback", "image", NULL,
"test-fallback", "image", NULL, NULL,
CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
CAIRO_CONTENT_COLOR, 0,
_cairo_boilerplate_test_fallback_create_surface, NULL,
NULL,
_cairo_boilerplate_test_fallback_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png
},
{
"test-fallback16", "image", NULL,
"test-fallback16", "image", NULL, NULL,
CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
CAIRO_CONTENT_COLOR_ALPHA, 0,
_cairo_boilerplate_test_fallback16_create_surface, NULL,
NULL,
_cairo_boilerplate_test_fallback16_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png
},
{
"test-fallback16", "image", NULL,
"test-fallback16", "image", NULL, NULL,
CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
CAIRO_CONTENT_COLOR, 0,
_cairo_boilerplate_test_fallback16_create_surface, NULL,
NULL,
_cairo_boilerplate_test_fallback16_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png
},
{
"test-meta", "image", NULL,
"test-meta", "image", NULL, NULL,
CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,
CAIRO_CONTENT_COLOR_ALPHA, 0,
_cairo_boilerplate_test_meta_create_surface, NULL,
NULL,
_cairo_boilerplate_test_meta_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
NULL, NULL,
FALSE, TRUE
},
{
"test-meta", "image", NULL,
"test-meta", "image", NULL, NULL,
CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,
CAIRO_CONTENT_COLOR, 0,
_cairo_boilerplate_test_meta_create_surface, NULL,
NULL,
_cairo_boilerplate_test_meta_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
NULL, NULL,
FALSE, TRUE
},
{
"test-paginated", "image", NULL,
"test-paginated", "image", NULL, NULL,
CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED,
CAIRO_CONTENT_COLOR_ALPHA, 0,
_cairo_boilerplate_test_paginated_create_surface, NULL,
NULL,
_cairo_boilerplate_test_paginated_create_surface,
NULL, NULL,
_cairo_boilerplate_test_paginated_get_image_surface,
_cairo_boilerplate_test_paginated_surface_write_to_png,
_cairo_boilerplate_test_paginated_cleanup,
@ -366,11 +366,11 @@ static const cairo_boilerplate_target_t targets[] =
FALSE, TRUE,
},
{
"test-paginated", "image", NULL,
"test-paginated", "image", NULL, NULL,
CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED,
CAIRO_CONTENT_COLOR, 0,
_cairo_boilerplate_test_paginated_create_surface, NULL,
NULL,
_cairo_boilerplate_test_paginated_create_surface,
NULL, NULL,
_cairo_boilerplate_test_paginated_get_image_surface,
_cairo_boilerplate_test_paginated_surface_write_to_png,
_cairo_boilerplate_test_paginated_cleanup,
@ -378,31 +378,32 @@ static const cairo_boilerplate_target_t targets[] =
FALSE, TRUE
},
{
"null", "image", NULL,
"null", "image", NULL, NULL,
CAIRO_INTERNAL_SURFACE_TYPE_NULL,
CAIRO_CONTENT_COLOR_ALPHA, 0,
_cairo_boilerplate_test_null_create_surface, NULL,
NULL, NULL, NULL,
_cairo_boilerplate_test_null_create_surface,
NULL, NULL,
NULL, NULL, NULL,
NULL,
TRUE, FALSE
},
#endif
#ifdef CAIRO_HAS_GLITZ_SURFACE
#if CAIRO_CAN_TEST_GLITZ_GLX_SURFACE
{
"glitz-glx", "glitz", NULL,
"glitz-glx", "glitz", NULL, NULL,
CAIRO_SURFACE_TYPE_GLITZ,CAIRO_CONTENT_COLOR_ALPHA, 0,
_cairo_boilerplate_glitz_glx_create_surface, NULL,
NULL,
_cairo_boilerplate_glitz_glx_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
_cairo_boilerplate_glitz_glx_cleanup
},
{
"glitz-glx", "glitz", NULL,
"glitz-glx", "glitz", NULL, NULL,
CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR, 0,
_cairo_boilerplate_glitz_glx_create_surface, NULL,
NULL,
_cairo_boilerplate_glitz_glx_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
_cairo_boilerplate_glitz_glx_cleanup
@ -410,19 +411,19 @@ static const cairo_boilerplate_target_t targets[] =
#endif
#if CAIRO_CAN_TEST_GLITZ_AGL_SURFACE
{
"glitz-agl", "glitz", NULL,
"glitz-agl", "glitz", NULL, NULL,
CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR_ALPHA, 0,
_cairo_boilerplate_glitz_agl_create_surface, NULL,
NULL,
_cairo_boilerplate_glitz_agl_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
_cairo_boilerplate_glitz_agl_cleanup
},
{
"glitz-agl", "glitz", NULL,
"glitz-agl", "glitz", NULL, NULL,
CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR, 0,
_cairo_boilerplate_glitz_agl_create_surface, NULL,
NULL,
_cairo_boilerplate_glitz_agl_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
_cairo_boilerplate_glitz_agl_cleanup
@ -430,19 +431,19 @@ static const cairo_boilerplate_target_t targets[] =
#endif
#if CAIRO_CAN_TEST_GLITZ_WGL_SURFACE
{
"glitz-wgl", "glitz", NULL,
"glitz-wgl", "glitz", NULL, NULL,
CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR_ALPHA, 0,
_cairo_boilerplate_glitz_wgl_create_surface, NULL,
NULL,
_cairo_boilerplate_glitz_wgl_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
_cairo_boilerplate_glitz_wgl_cleanup
},
{
"glitz-wgl", "glitz", NULL,
"glitz-wgl", "glitz", NULL, NULL,
CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR, 0,
_cairo_boilerplate_glitz_wgl_create_surface, NULL,
NULL,
_cairo_boilerplate_glitz_wgl_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
_cairo_boilerplate_glitz_wgl_cleanup
@ -451,19 +452,19 @@ static const cairo_boilerplate_target_t targets[] =
#endif /* CAIRO_HAS_GLITZ_SURFACE */
#if CAIRO_HAS_QT_SURFACE
{
"qt", "qt", NULL,
"qt", "qt", NULL, NULL,
CAIRO_SURFACE_TYPE_QT, CAIRO_CONTENT_COLOR_ALPHA, 0,
_cairo_boilerplate_qt_create_surface, NULL,
NULL,
_cairo_boilerplate_qt_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
_cairo_boilerplate_qt_cleanup
},
{
"qt", "qt", NULL,
"qt", "qt", NULL, NULL,
CAIRO_SURFACE_TYPE_QT, CAIRO_CONTENT_COLOR, 0,
_cairo_boilerplate_qt_create_surface, NULL,
NULL,
_cairo_boilerplate_qt_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
_cairo_boilerplate_qt_cleanup
@ -471,19 +472,19 @@ static const cairo_boilerplate_target_t targets[] =
#endif
#if CAIRO_HAS_QUARTZ_SURFACE
{
"quartz", "quartz", NULL,
"quartz", "quartz", NULL, NULL,
CAIRO_SURFACE_TYPE_QUARTZ, CAIRO_CONTENT_COLOR_ALPHA, 0,
_cairo_boilerplate_quartz_create_surface, NULL,
NULL,
_cairo_boilerplate_quartz_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
_cairo_boilerplate_quartz_cleanup
},
{
"quartz", "quartz", NULL,
"quartz", "quartz", NULL, NULL,
CAIRO_SURFACE_TYPE_QUARTZ, CAIRO_CONTENT_COLOR, 0,
_cairo_boilerplate_quartz_create_surface, NULL,
NULL,
_cairo_boilerplate_quartz_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
_cairo_boilerplate_quartz_cleanup
@ -491,10 +492,10 @@ static const cairo_boilerplate_target_t targets[] =
#endif
#if CAIRO_HAS_WIN32_SURFACE
{
"win32", "win32", NULL,
"win32", "win32", NULL, NULL,
CAIRO_SURFACE_TYPE_WIN32, CAIRO_CONTENT_COLOR, 0,
_cairo_boilerplate_win32_create_surface, NULL,
NULL,
_cairo_boilerplate_win32_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png
},
@ -502,30 +503,30 @@ static const cairo_boilerplate_target_t targets[] =
* ARGB images it just chains to the image backend
*/
{
"win32", "win32", NULL,
"win32", "win32", NULL, NULL,
CAIRO_SURFACE_TYPE_WIN32, CAIRO_CONTENT_COLOR_ALPHA, 0,
_cairo_boilerplate_win32_create_surface, NULL,
NULL,
_cairo_boilerplate_win32_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png
},
#if CAIRO_CAN_TEST_WIN32_PRINTING_SURFACE
{
"win32-printing", "win32", ".ps",
"win32-printing", "win32", ".ps", NULL,
CAIRO_SURFACE_TYPE_WIN32_PRINTING,
CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED, 0,
_cairo_boilerplate_win32_printing_create_surface, NULL,
NULL,
_cairo_boilerplate_win32_printing_create_surface,
NULL, NULL,
_cairo_boilerplate_win32_printing_get_image_surface,
_cairo_boilerplate_win32_printing_surface_write_to_png,
_cairo_boilerplate_win32_printing_cleanup,
NULL, TRUE, TRUE
},
{
"win32-printing", "win32", ".ps",
"win32-printing", "win32", ".ps", NULL,
CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR, 0,
_cairo_boilerplate_win32_printing_create_surface, NULL,
NULL,
_cairo_boilerplate_win32_printing_create_surface,
NULL, NULL,
_cairo_boilerplate_win32_printing_get_image_surface,
_cairo_boilerplate_win32_printing_surface_write_to_png,
_cairo_boilerplate_win32_printing_cleanup,
@ -537,10 +538,10 @@ static const cairo_boilerplate_target_t targets[] =
/* Acceleration architectures may make the results differ by a
* bit, so we set the error tolerance to 1. */
{
"xcb", "xcb", NULL,
"xcb", "xcb", NULL, NULL,
CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR_ALPHA, 1,
_cairo_boilerplate_xcb_create_surface, NULL,
NULL,
_cairo_boilerplate_xcb_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
_cairo_boilerplate_xcb_cleanup,
@ -551,19 +552,20 @@ static const cairo_boilerplate_target_t targets[] =
/* Acceleration architectures may make the results differ by a
* bit, so we set the error tolerance to 1. */
{
"xlib", "xlib", NULL,
"xlib", "xlib", NULL, "xlib-fallback",
CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR_ALPHA, 1,
_cairo_boilerplate_xlib_create_surface, NULL,
NULL,
_cairo_boilerplate_xlib_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
_cairo_boilerplate_xlib_cleanup,
_cairo_boilerplate_xlib_synchronize
},
{
"xlib", "xlib", NULL, CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1,
_cairo_boilerplate_xlib_create_surface, NULL,
NULL,
"xlib", "xlib", NULL, "xlib-fallback",
CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1,
_cairo_boilerplate_xlib_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
_cairo_boilerplate_xlib_cleanup,
@ -574,10 +576,10 @@ static const cairo_boilerplate_target_t targets[] =
/* This is a fallback surface which uses xlib fallbacks instead of
* the Render extension. */
{
"xlib-fallback", "xlib", NULL,
"xlib-fallback", "xlib", NULL, NULL,
CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1,
_cairo_boilerplate_xlib_fallback_create_surface, NULL,
NULL,
_cairo_boilerplate_xlib_fallback_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
_cairo_boilerplate_xlib_cleanup,
@ -586,7 +588,7 @@ static const cairo_boilerplate_target_t targets[] =
#endif
#if CAIRO_HAS_PS_SURFACE && CAIRO_CAN_TEST_PS_SURFACE
{
"ps2", "ps", ".ps",
"ps2", "ps", ".ps", NULL,
CAIRO_SURFACE_TYPE_PS,
CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED, 0,
_cairo_boilerplate_ps2_create_surface,
@ -598,7 +600,7 @@ static const cairo_boilerplate_target_t targets[] =
NULL, TRUE, TRUE
},
{
"ps2", "ps", ".ps",
"ps2", "ps", ".ps", NULL,
CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR, 0,
_cairo_boilerplate_ps2_create_surface,
_cairo_boilerplate_ps_force_fallbacks,
@ -609,7 +611,7 @@ static const cairo_boilerplate_target_t targets[] =
NULL, TRUE, TRUE
},
{
"ps3", "ps", ".ps",
"ps3", "ps", ".ps", NULL,
CAIRO_SURFACE_TYPE_PS,
CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED, 0,
_cairo_boilerplate_ps3_create_surface,
@ -621,7 +623,7 @@ static const cairo_boilerplate_target_t targets[] =
NULL, TRUE, TRUE
},
{
"ps3", "ps", ".ps",
"ps3", "ps", ".ps", NULL,
CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR, 0,
_cairo_boilerplate_ps3_create_surface,
_cairo_boilerplate_ps_force_fallbacks,
@ -634,7 +636,7 @@ static const cairo_boilerplate_target_t targets[] =
#endif
#if CAIRO_HAS_PDF_SURFACE && CAIRO_CAN_TEST_PDF_SURFACE
{
"pdf", "pdf", ".pdf",
"pdf", "pdf", ".pdf", NULL,
CAIRO_SURFACE_TYPE_PDF,
CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED, 0,
_cairo_boilerplate_pdf_create_surface,
@ -646,7 +648,7 @@ static const cairo_boilerplate_target_t targets[] =
NULL, TRUE, TRUE
},
{
"pdf", "pdf", ".pdf",
"pdf", "pdf", ".pdf", NULL,
CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR, 0,
_cairo_boilerplate_pdf_create_surface,
_cairo_boilerplate_pdf_force_fallbacks,
@ -659,7 +661,7 @@ static const cairo_boilerplate_target_t targets[] =
#endif
#if CAIRO_HAS_SCRIPT_SURFACE
{
"script", "script", ".cs",
"script", "script", ".cs", NULL,
CAIRO_SURFACE_TYPE_SCRIPT, CAIRO_CONTENT_COLOR_ALPHA, 0,
_cairo_boilerplate_script_create_surface,
NULL,
@ -677,7 +679,7 @@ static const cairo_boilerplate_target_t targets[] =
* tests. XXX: I'd still like to chase these down at some point.
* For now just set the svg error tolerance to 1. */
{
"svg11", "svg", NULL,
"svg11", "svg", NULL, NULL,
CAIRO_SURFACE_TYPE_SVG, CAIRO_CONTENT_COLOR_ALPHA, 1,
_cairo_boilerplate_svg11_create_surface,
_cairo_boilerplate_svg_force_fallbacks,
@ -688,7 +690,7 @@ static const cairo_boilerplate_target_t targets[] =
NULL, TRUE, TRUE
},
{
"svg11", "svg", NULL,
"svg11", "svg", NULL, NULL,
CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR, 1,
_cairo_boilerplate_svg11_create_surface,
_cairo_boilerplate_svg_force_fallbacks,
@ -699,7 +701,7 @@ static const cairo_boilerplate_target_t targets[] =
NULL, TRUE, TRUE
},
{
"svg12", "svg", NULL,
"svg12", "svg", NULL, NULL,
CAIRO_SURFACE_TYPE_SVG, CAIRO_CONTENT_COLOR_ALPHA, 1,
_cairo_boilerplate_svg12_create_surface,
_cairo_boilerplate_svg_force_fallbacks,
@ -710,7 +712,7 @@ static const cairo_boilerplate_target_t targets[] =
NULL, TRUE, TRUE
},
{
"svg12", "svg", NULL,
"svg12", "svg", NULL, NULL,
CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR, 1,
_cairo_boilerplate_svg12_create_surface,
_cairo_boilerplate_svg_force_fallbacks,
@ -726,28 +728,28 @@ static const cairo_boilerplate_target_t targets[] =
* is related to the fact that it doesn't use premultiplied alpha...
* Just ignore the small difference. */
{
"beos", "beos", NULL,
"beos", "beos", NULL, NULL,
CAIRO_SURFACE_TYPE_BEOS, CAIRO_CONTENT_COLOR, 1,
_cairo_boilerplate_beos_create_surface, NULL,
NULL,
_cairo_boilerplate_beos_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
_cairo_boilerplate_beos_cleanup
},
{
"beos-bitmap", "beos", NULL,
"beos-bitmap", "beos", NULL, NULL,
CAIRO_SURFACE_TYPE_BEOS, CAIRO_CONTENT_COLOR, 1,
_cairo_boilerplate_beos_create_surface_for_bitmap, NULL,
NULL,
_cairo_boilerplate_beos_create_surface_for_bitmap,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
_cairo_boilerplate_beos_cleanup_bitmap
},
{
"beos-bitmap", "beos", NULL,
"beos-bitmap", "beos", NULL, NULL,
CAIRO_SURFACE_TYPE_BEOS, CAIRO_CONTENT_COLOR_ALPHA, 1,
_cairo_boilerplate_beos_create_surface_for_bitmap, NULL,
NULL,
_cairo_boilerplate_beos_create_surface_for_bitmap,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
_cairo_boilerplate_beos_cleanup_bitmap
@ -756,19 +758,19 @@ static const cairo_boilerplate_target_t targets[] =
#if CAIRO_HAS_DIRECTFB_SURFACE
{
"directfb", "directfb", NULL,
"directfb", "directfb", NULL, NULL,
CAIRO_SURFACE_TYPE_DIRECTFB, CAIRO_CONTENT_COLOR, 0,
_cairo_boilerplate_directfb_create_surface, NULL,
NULL,
_cairo_boilerplate_directfb_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
_cairo_boilerplate_directfb_cleanup
},
{
"directfb-bitmap", "directfb", NULL,
"directfb-bitmap", "directfb", NULL, NULL,
CAIRO_SURFACE_TYPE_DIRECTFB, CAIRO_CONTENT_COLOR_ALPHA, 0,
_cairo_boilerplate_directfb_create_surface, NULL,
NULL,
_cairo_boilerplate_directfb_create_surface,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
_cairo_boilerplate_directfb_cleanup
@ -899,6 +901,32 @@ cairo_boilerplate_get_image_target (cairo_content_t content)
return NULL;
}
const cairo_boilerplate_target_t *
cairo_boilerplate_get_target_by_name (const char *name,
cairo_content_t content)
{
int num_targets, i;
num_targets = sizeof (targets) / sizeof (targets[0]);
/* first return an exact match */
for (i = 0; i < num_targets; i++) {
if (strcmp (targets[i].name, name) == 0 &&
targets[i].content == content)
{
return &targets[i];
}
}
/* otherwise just return a match that may differ in content */
for (i = 0; i < num_targets; i++) {
if (strcmp (targets[i].name, name) == 0)
return &targets[i];
}
return NULL;
}
void
cairo_boilerplate_free_targets (const cairo_boilerplate_target_t **targets)
{

View file

@ -152,6 +152,7 @@ typedef struct _cairo_boilerplate_target
const char *name;
const char *basename;
const char *file_extension;
const char *reference_target;
cairo_surface_type_t expected_type;
cairo_content_t content;
unsigned int error_tolerance;
@ -169,6 +170,10 @@ typedef struct _cairo_boilerplate_target
const cairo_boilerplate_target_t *
cairo_boilerplate_get_image_target (cairo_content_t content);
const cairo_boilerplate_target_t *
cairo_boilerplate_get_target_by_name (const char *name,
cairo_content_t content);
const cairo_boilerplate_target_t **
cairo_boilerplate_get_targets (int *num_targets, cairo_bool_t *limited_targets);

View file

@ -100,14 +100,18 @@ endif
if HAVE_SHM
EXTRA_PROGRAMS += cairo-test-trace
cairo_test_trace_SOURCES = \
cairo-test-trace.c
cairo-test-trace.c \
buffer-diff.c \
buffer-diff.h
cairo_test_trace_LDADD = \
$(top_builddir)/test/pdiff/libpdiff.la \
$(top_builddir)/util/cairo-script/libcairo-script-interpreter.la \
$(top_builddir)/boilerplate/libcairoboilerplate.la \
$(top_builddir)/src/libcairo.la \
$(CAIRO_LDADD) \
$(SHM_LIBS)
cairo_test_trace_DEPENDENCIES = \
$(top_builddir)/test/pdiff/libpdiff.la \
$(top_builddir)/util/cairo-script/libcairo-script-interpreter.la \
$(top_builddir)/boilerplate/libcairoboilerplate.la \
$(top_builddir)/src/libcairo.la

View file

@ -55,6 +55,7 @@
#define _GNU_SOURCE 1 /* getline() */
#include "cairo-test.h"
#include "buffer-diff.h"
#include "cairo-boilerplate-getopt.h"
#include <cairo-script-interpreter.h>
@ -82,7 +83,7 @@
#include <fontconfig/fontconfig.h>
#endif
#define DATA_SIZE (64 << 20)
#define DATA_SIZE (256 << 20)
#define SHM_PATH_XXX "/shmem-cairo-trace"
typedef struct _test_runner {
@ -106,9 +107,12 @@ typedef struct _test_runner_thread {
pid_t pid;
int sk;
struct context_list {
struct context_list *next;
cairo_script_interpreter_t *csi;
struct context_closure {
struct context_closure *next;
unsigned long id;
unsigned long start_line;
unsigned long end_line;
cairo_t *context;
cairo_surface_t *surface;
} *contexts;
@ -121,12 +125,19 @@ struct slave {
int fd;
unsigned long image_serial;
unsigned long image_ready;
unsigned long start_line;
unsigned long end_line;
cairo_surface_t *image;
cairo_surface_t *difference;
buffer_diff_result_t result;
const cairo_boilerplate_target_t *target;
const struct slave *reference;
};
struct request_image {
unsigned long id;
unsigned long start_line;
unsigned long end_line;
cairo_format_t format;
int width;
int height;
@ -212,11 +223,16 @@ format_for_content (cairo_content_t content)
static void *
request_image (test_runner_thread_t *thread,
unsigned long id,
struct context_closure *closure,
cairo_format_t format,
int width, int height, int stride)
{
struct request_image rq = { id, format, width, height, stride };
const struct request_image rq = {
closure->id,
closure->start_line,
closure->end_line,
format, width, height, stride
};
size_t offset = -1;
writen (thread->sk, &rq, sizeof (rq));
@ -229,9 +245,9 @@ request_image (test_runner_thread_t *thread,
static void
push_surface (test_runner_thread_t *thread,
cairo_surface_t *source,
unsigned long id)
struct context_closure *closure)
{
cairo_surface_t *source = closure->surface;
cairo_surface_t *image;
cairo_format_t format = (cairo_format_t) -1;
cairo_t *cr;
@ -271,7 +287,7 @@ push_surface (test_runner_thread_t *thread,
stride = cairo_format_stride_for_width (format, width);
data = request_image (thread, id, format, width, height, stride);
data = request_image (thread, closure, format, width, height, stride);
if (data == NULL)
exit (-1);
@ -288,12 +304,12 @@ push_surface (test_runner_thread_t *thread,
cairo_destroy (cr);
/* signal completion */
writen (thread->sk, &id, sizeof (id));
writen (thread->sk, &closure->id, sizeof (closure->id));
/* wait for image check */
serial = 0;
readn (thread->sk, &serial, sizeof (serial));
if (serial != id)
if (serial != closure->id)
exit (-1);
}
@ -324,10 +340,12 @@ static cairo_t *
_context_create (void *closure, cairo_surface_t *surface)
{
test_runner_thread_t *thread = closure;
struct context_list *l;
struct context_closure *l;
l = xmalloc (sizeof (*l));
l->next = thread->contexts;
l->start_line = cairo_script_interpreter_get_line_number (thread->csi);
l->end_line = l->start_line;
l->context = cairo_create (surface);
l->surface = cairo_surface_reference (surface);
l->id = ++thread->context_id;
@ -342,17 +360,19 @@ static void
_context_destroy (void *closure, void *ptr)
{
test_runner_thread_t *thread = closure;
struct context_list *l, **prev = &thread->contexts;
struct context_closure *l, **prev = &thread->contexts;
while ((l = *prev) != NULL) {
if (l->context == ptr) {
l->end_line =
cairo_script_interpreter_get_line_number (thread->csi);
if (cairo_surface_status (l->surface) == CAIRO_STATUS_SUCCESS) {
push_surface (thread, l->surface, l->id);
push_surface (thread, l);
} else {
fprintf (stderr, "%s: error during replay: %s!\n",
fprintf (stderr, "%s: error during replay, line %lu: %s!\n",
thread->target->name,
cairo_status_to_string (cairo_surface_status
(l->surface)));
l->end_line,
cairo_status_to_string (cairo_surface_status (l->surface)));
exit (1);
}
@ -375,15 +395,14 @@ execute (test_runner_thread_t *thread,
.context_create = _context_create,
.context_destroy = _context_destroy,
};
cairo_script_interpreter_t *csi;
csi = cairo_script_interpreter_create ();
cairo_script_interpreter_install_hooks (csi, &hooks);
thread->csi = cairo_script_interpreter_create ();
cairo_script_interpreter_install_hooks (thread->csi, &hooks);
cairo_script_interpreter_run (csi, trace);
cairo_script_interpreter_run (thread->csi, trace);
cairo_script_interpreter_finish (csi);
if (cairo_script_interpreter_destroy (csi))
cairo_script_interpreter_finish (thread->csi);
if (cairo_script_interpreter_destroy (thread->csi))
exit (1);
}
@ -463,7 +482,7 @@ spawn_target (const char *socket_path,
thread.context_id = 0;
thread.surface = target->create_surface (NULL,
CAIRO_CONTENT_COLOR_ALPHA,
target->content,
1, 1,
1, 1,
CAIRO_BOILERPLATE_MODE_TEST,
@ -491,10 +510,12 @@ spawn_target (const char *socket_path,
/* XXX imagediff - is the extra expense worth it? */
static cairo_bool_t
matching_images (cairo_surface_t *a, cairo_surface_t *b)
matches_reference (struct slave *slave)
{
if (a == NULL || b == NULL)
return FALSE;
cairo_surface_t *a, *b;
a = slave->image;
b = slave->reference->image;
if (cairo_surface_status (a) || cairo_surface_status (b))
return FALSE;
@ -514,10 +535,46 @@ matching_images (cairo_surface_t *a, cairo_surface_t *b)
if (cairo_image_surface_get_stride (a) != cairo_image_surface_get_stride (b))
return FALSE;
return memcmp (cairo_image_surface_get_data (a),
cairo_image_surface_get_data (b),
cairo_image_surface_get_stride (a) *
cairo_image_surface_get_stride (b));
if (FALSE && cairo_surface_get_content (a) & CAIRO_CONTENT_COLOR) {
cairo_surface_t *diff;
int width, height, stride, size;
unsigned char *data;
cairo_status_t status;
width = cairo_image_surface_get_width (a);
height = cairo_image_surface_get_height (a);
stride = cairo_image_surface_get_stride (a);
size = height * stride * 4;
data = malloc (size);
if (data == NULL)
return FALSE;
diff = cairo_image_surface_create_for_data (data,
cairo_image_surface_get_format (a),
width, height, stride);
cairo_surface_set_user_data (diff, (cairo_user_data_key_t *) diff,
data, free);
status = image_diff (NULL, a, b, diff, &slave->result);
if (status) {
cairo_surface_destroy (diff);
return FALSE;
}
if (slave->result.pixels_changed &&
slave->result.max_diff > slave->target->error_tolerance) {
slave->difference = diff;
return FALSE;
} else {
cairo_surface_destroy (diff);
return TRUE;
}
} else {
return memcmp (cairo_image_surface_get_data (a),
cairo_image_surface_get_data (b),
cairo_image_surface_get_stride (a) *
cairo_image_surface_get_stride (b));
}
}
static cairo_bool_t
@ -528,7 +585,10 @@ check_images (struct slave *slaves, int num_slaves)
for (n = 1; n < num_slaves; n++) {
assert (slaves[n].image_ready == slaves[0].image_ready);
if (! matching_images (slaves[n].image, slaves[0].image))
if (slaves[n].reference == NULL)
continue;
if (! matches_reference (&slaves[n]))
return FALSE;
}
@ -546,6 +606,13 @@ write_images (const char *trace, struct slave *slave, int num_slaves)
trace, slave->target->name);
cairo_surface_write_to_png (slave->image, filename);
free (filename);
if (slave->difference) {
xasprintf (&filename, "%s-%s-diff.png",
trace, slave->target->name);
cairo_surface_write_to_png (slave->difference, filename);
free (filename);
}
}
slave++;
@ -561,6 +628,8 @@ allocate_image_for_slave (uint8_t *base, size_t offset, struct slave *slave)
readn (slave->fd, &rq, sizeof (rq));
slave->image_serial = rq.id;
slave->start_line = rq.start_line;
slave->end_line = rq.end_line;
size = rq.height * rq.stride;
size = (size + 127) & -128;
@ -576,12 +645,19 @@ allocate_image_for_slave (uint8_t *base, size_t offset, struct slave *slave)
return offset;
}
struct error_info {
unsigned long context_id;
unsigned long start_line;
unsigned long end_line;
};
static cairo_bool_t
test_run (void *base,
int sk,
const char *trace,
struct slave *slaves,
int num_slaves)
int num_slaves,
struct error_info *error)
{
struct pollfd *pfd;
int npfd, cnt, n, i;
@ -672,6 +748,10 @@ test_run (void *base,
if (completion == num_slaves) {
if (! check_images (slaves, num_slaves)) {
error->context_id = slaves[0].image_serial;
error->start_line = slaves[0].start_line;
error->end_line = slaves[0].end_line;
write_images (trace, slaves, num_slaves);
goto out;
}
@ -710,6 +790,9 @@ out:
cairo_surface_destroy (slaves[n].image);
slaves[n].image = NULL;
cairo_surface_destroy (slaves[n].difference);
slaves[n].difference = NULL;
slaves[n].image_serial = 0;
slaves[n].image_ready = 0;
ret = FALSE;
@ -744,16 +827,17 @@ target_is_measurable (const cairo_boilerplate_target_t *target)
case CAIRO_SURFACE_TYPE_XCB:
case CAIRO_SURFACE_TYPE_GLITZ:
case CAIRO_SURFACE_TYPE_QUARTZ:
case CAIRO_SURFACE_TYPE_QUARTZ_IMAGE:
case CAIRO_SURFACE_TYPE_WIN32:
case CAIRO_SURFACE_TYPE_BEOS:
case CAIRO_SURFACE_TYPE_DIRECTFB:
#if CAIRO_VERSION > CAIRO_VERSION_ENCODE(1,1,2)
case CAIRO_SURFACE_TYPE_OS2:
#endif
case CAIRO_SURFACE_TYPE_QT:
return TRUE;
case CAIRO_SURFACE_TYPE_PDF:
case CAIRO_SURFACE_TYPE_PS:
case CAIRO_SURFACE_TYPE_SCRIPT:
case CAIRO_SURFACE_TYPE_SVG:
case CAIRO_SURFACE_TYPE_WIN32_PRINTING:
default:
@ -814,7 +898,10 @@ server_shm (const char *shm_path)
}
static cairo_bool_t
_test_trace (test_runner_t *test, const char *trace, const char *name)
_test_trace (test_runner_t *test,
const char *trace,
const char *name,
struct error_info *error)
{
const char *shm_path = SHM_PATH_XXX;
const cairo_boilerplate_target_t *target, *image;
@ -851,21 +938,51 @@ _test_trace (test_runner_t *test, const char *trace, const char *name)
assert (image != NULL);
/* spawn slave processes to run the trace */
s = slaves = xcalloc (test->num_targets + 1, sizeof (struct slave));
s = slaves = xcalloc (2*test->num_targets + 1, sizeof (struct slave));
s->pid = spawn_target (socket_path, shm_path, image, trace);
if (s->pid < 0)
goto cleanup;
s->target = image;
s->reference = NULL;
s->fd = -1;
s++;
for (i = 0; i < test->num_targets; i++) {
pid_t slave;
const cairo_boilerplate_target_t *reference;
struct slave *master;
target = test->targets[i];
if (target == image || ! target_is_measurable (target))
continue;
/* find a matching slave to use as a reference for this target */
if (target->reference_target != NULL) {
reference =
cairo_boilerplate_get_target_by_name (target->reference_target,
target->content);
assert (reference != NULL);
} else {
reference = image;
}
for (master = slaves; master < s; master++) {
if (master->target == reference)
break;
}
if (master == s) {
/* no match found, spawn a slave to render the reference image */
slave = spawn_target (socket_path, shm_path, reference, trace);
if (slave < 0)
continue;
s->pid = slave;
s->target = reference;
s->fd = -1;
s->reference = NULL;
s++;
}
slave = spawn_target (socket_path, shm_path, target, trace);
if (slave < 0)
continue;
@ -873,6 +990,7 @@ _test_trace (test_runner_t *test, const char *trace, const char *name)
s->pid = slave;
s->target = target;
s->fd = -1;
s->reference = master;
s++;
}
num_slaves = s - slaves;
@ -886,7 +1004,7 @@ _test_trace (test_runner_t *test, const char *trace, const char *name)
fprintf (stderr, "Unable to mmap shared memory\n");
goto cleanup;
}
ret = test_run (base, sk, name, slaves, num_slaves);
ret = test_run (base, sk, name, slaves, num_slaves, error);
munmap (base, DATA_SIZE);
cleanup:
@ -927,13 +1045,25 @@ test_trace (test_runner_t *test, const char *trace)
if (test->list_only) {
printf ("%s\n", name);
} else {
struct error_info error = {0};
cairo_bool_t ret;
printf ("%s: ", name);
fflush (stdout);
ret = _test_trace (test, trace, name);
printf ("%s\n", ret ? "PASS" : "FAIL");
ret = _test_trace (test, trace, name, &error);
if (ret) {
printf ("PASS\n");
} else {
if (error.context_id) {
printf ("FAIL (context %lu, lines [%lu, %lu])\n",
error.context_id,
error.start_line,
error.end_line);
} else {
printf ("FAIL\n");
}
}
}
free (trace_cpy);
@ -1258,3 +1388,24 @@ main (int argc, char *argv[])
return 0;
}
void
cairo_test_logv (const cairo_test_context_t *ctx,
const char *fmt, va_list va)
{
#if 0
vfprintf (stderr, fmt, va);
#endif
}
void
cairo_test_log (const cairo_test_context_t *ctx, const char *fmt, ...)
{
#if 0
va_list va;
va_start (va, fmt);
vfprintf (stderr, fmt, va);
va_end (va);
#endif
}