[cairo-commit] 2 commits - src/cairo-image-compositor.c test/recordflip.c test/reference

Chris Wilson ickle at kemper.freedesktop.org
Thu Oct 2 05:12:21 PDT 2014


 src/cairo-image-compositor.c                                   |   32 +
 test/recordflip.c                                              |  188 ++++++++++
 test/reference/recordflip-whole-fill-alpha.ref.png             |binary
 test/reference/recordflip-whole-paint-alpha-clip-mask.ref.png  |binary
 test/reference/recordflip-whole-paint-alpha-clip.ref.png       |binary
 test/reference/recordflip-whole-paint-alpha-solid-clip.ref.png |binary
 test/reference/recordflip-whole-paint-alpha.ref.png            |binary
 test/reference/recordflip-whole-paint.ref.png                  |binary
 test/reference/recordflip-whole-select-font-face.ref.png       |binary
 test/reference/recordflip-whole-self-intersecting.ref.png      |binary
 test/reference/recordflip-whole-text-transform.ref.png         |binary
 11 files changed, 220 insertions(+)

New commits:
commit 14df211b9c12719f67412aedd6610eb623df7d7e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Oct 2 13:08:50 2014 +0100

    test: Add whole flipped replays
    
    When investing the symmetry of the raterisation, we want to have a
    simple replay of all of the original geometry through a the flipped
    recording surface. This reduces the worry about artifacts from the
    clipped rendering.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/test/recordflip.c b/test/recordflip.c
index 7ddf21e..e923c8a 100644
--- a/test/recordflip.c
+++ b/test/recordflip.c
@@ -436,6 +436,84 @@ record_replay (cairo_t *cr, cairo_t *(*func)(cairo_t *), int width, int height)
 }
 
 static cairo_test_status_t
+record_whole_replay (cairo_t *cr, cairo_t *(*func)(cairo_t *), int width, int height)
+{
+    cairo_surface_t *surface;
+
+#if GENERATE_REF
+    {
+	cairo_surface_t *image;
+	uint8_t *data, *tmp;
+	int stride, bpp;
+	int x, y;
+
+	surface = cairo_get_target (cr);
+
+	func(cr);
+
+	image = cairo_surface_map_to_image (surface, NULL);
+
+	switch (cairo_image_surface_get_format (image)) {
+	case CAIRO_FORMAT_ARGB32:
+	case CAIRO_FORMAT_RGB24:
+	case CAIRO_FORMAT_RGB30:
+	    bpp=4;
+	    break;
+	case CAIRO_FORMAT_RGB16_565:
+	    bpp=2;
+	    break;
+	case CAIRO_FORMAT_A8:
+	    bpp=1;
+	    break;
+	case CAIRO_FORMAT_A1:
+	case CAIRO_FORMAT_INVALID:
+	default:
+	    return CAIRO_TEST_FAILURE;
+	}
+
+	data = cairo_image_surface_get_data (image);
+	stride = cairo_image_surface_get_stride (image);
+
+	tmp = malloc (stride);
+	if (tmp == NULL)
+	    return CAIRO_TEST_FAILURE;
+
+	for (y = 0; y < height; y++) {
+	    uint8_t *row = data + y * stride;
+	    for (x = 0; x < width/2; x++) {
+		memcpy (tmp, row + bpp * x, bpp);
+		memcpy (row + bpp * x, row + bpp * (width - x - 1), bpp);
+		memcpy (row + bpp * (width - x - 1), tmp, bpp);
+	    }
+	}
+
+	for (y = 0; y < height/2; y++) {
+	    memcpy (tmp, data + y * stride, stride);
+	    memcpy (data + y * stride, data + (height - y - 1) * stride, stride);
+	    memcpy (data + (height - y - 1) * stride, tmp, stride);
+	}
+
+	free (tmp);
+
+	cairo_surface_unmap_image (surface, image);
+    }
+#else
+    surface = record_get (func (record_create (cr)));
+
+    cairo_scale (cr, -1, -1);
+    cairo_translate (cr, -width, -height);
+    cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+    cairo_set_source_surface (cr, surface, 0, 0);
+    cairo_surface_destroy (surface);
+    cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_NONE);
+
+    cairo_paint (cr);
+#endif
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
 record_paint (cairo_t *cr, int width, int height)
 {
     return record_replay (cr, paint, width, height);
@@ -489,6 +567,116 @@ record_text_transform (cairo_t *cr, int width, int height)
     return record_replay (cr, text_transform, width, height);
 }
 
+static cairo_test_status_t
+record_whole_paint (cairo_t *cr, int width, int height)
+{
+    return record_whole_replay (cr, paint, width, height);
+}
+
+static cairo_test_status_t
+record_whole_paint_alpha (cairo_t *cr, int width, int height)
+{
+    return record_whole_replay (cr, paint_alpha, width, height);
+}
+
+static cairo_test_status_t
+record_whole_paint_alpha_solid_clip (cairo_t *cr, int width, int height)
+{
+    return record_whole_replay (cr, paint_alpha_solid_clip, width, height);
+}
+
+static cairo_test_status_t
+record_whole_paint_alpha_clip (cairo_t *cr, int width, int height)
+{
+    return record_whole_replay (cr, paint_alpha_clip, width, height);
+}
+
+static cairo_test_status_t
+record_whole_paint_alpha_clip_mask (cairo_t *cr, int width, int height)
+{
+    return record_whole_replay (cr, paint_alpha_clip_mask, width, height);
+}
+
+static cairo_test_status_t
+record_whole_fill_alpha (cairo_t *cr, int width, int height)
+{
+    return record_whole_replay (cr, fill_alpha, width, height);
+}
+
+static cairo_test_status_t
+record_whole_self_intersecting (cairo_t *cr, int width, int height)
+{
+    return record_whole_replay (cr, self_intersecting, width, height);
+}
+
+static cairo_test_status_t
+record_whole_select_font_face (cairo_t *cr, int width, int height)
+{
+    return record_whole_replay (cr, select_font_face, width, height);
+}
+
+static cairo_test_status_t
+record_whole_text_transform (cairo_t *cr, int width, int height)
+{
+    return record_whole_replay (cr, text_transform, width, height);
+}
+
+CAIRO_TEST (recordflip_whole_paint,
+	    "Test replayed calls to cairo_paint",
+	    "paint,record", /* keywords */
+	    NULL, /* requirements */
+	    8, 8,
+	    NULL, record_whole_paint)
+CAIRO_TEST (recordflip_whole_paint_alpha,
+	    "Simple test of cairo_paint_with_alpha",
+	    "record, paint, alpha", /* keywords */
+	    NULL, /* requirements */
+	    32, 32,
+	    NULL, record_whole_paint_alpha)
+CAIRO_TEST (recordflip_whole_paint_alpha_solid_clip,
+	    "Simple test of cairo_paint_with_alpha+unaligned clip",
+	    "record, paint, alpha, clip", /* keywords */
+	    NULL, /* requirements */
+	    32, 32,
+	    NULL, record_whole_paint_alpha_solid_clip)
+CAIRO_TEST (recordflip_whole_paint_alpha_clip,
+	    "Simple test of cairo_paint_with_alpha+unaligned clip",
+	    "record, paint, alpha, clip", /* keywords */
+	    NULL, /* requirements */
+	    32, 32,
+	    NULL, record_whole_paint_alpha_clip)
+CAIRO_TEST (recordflip_whole_paint_alpha_clip_mask,
+	    "Simple test of cairo_paint_with_alpha+triangular clip",
+	    "record, paint, alpha, clip", /* keywords */
+	    NULL, /* requirements */
+	    32, 32,
+	    NULL, record_whole_paint_alpha_clip_mask)
+CAIRO_TEST (recordflip_whole_fill_alpha,
+	    "Tests using set_rgba();fill()",
+	    "record,fill, alpha", /* keywords */
+	    NULL, /* requirements */
+	    (2*SIZE + 4*PAD), (2*SIZE + 4*PAD),
+	    NULL, record_whole_fill_alpha)
+CAIRO_TEST (recordflip_whole_select_font_face,
+	    "Tests using cairo_select_font_face to draw text in different faces",
+	    "record, font", /* keywords */
+	    NULL, /* requirements */
+	    192, (TEXT_SIZE + 4),
+	    NULL, record_whole_select_font_face)
+CAIRO_TEST (recordflip_whole_self_intersecting,
+	    "Test strokes of self-intersecting paths",
+	    "record, stroke, trap", /* keywords */
+	    NULL, /* requirements */
+	    10, 20,
+	    NULL, record_whole_self_intersecting)
+CAIRO_TEST (recordflip_whole_text_transform,
+	    "Test various applications of the font matrix",
+	    "record, text, transform", /* keywords */
+	    NULL, /* requirements */
+	    TT_SIZE, TT_SIZE,
+	    NULL, record_whole_text_transform)
+
+
 CAIRO_TEST (recordflip_paint,
 	    "Test replayed calls to cairo_paint",
 	    "paint,record", /* keywords */
diff --git a/test/reference/recordflip-whole-fill-alpha.ref.png b/test/reference/recordflip-whole-fill-alpha.ref.png
new file mode 100644
index 0000000..289a915
Binary files /dev/null and b/test/reference/recordflip-whole-fill-alpha.ref.png differ
diff --git a/test/reference/recordflip-whole-paint-alpha-clip-mask.ref.png b/test/reference/recordflip-whole-paint-alpha-clip-mask.ref.png
new file mode 100644
index 0000000..842fa35
Binary files /dev/null and b/test/reference/recordflip-whole-paint-alpha-clip-mask.ref.png differ
diff --git a/test/reference/recordflip-whole-paint-alpha-clip.ref.png b/test/reference/recordflip-whole-paint-alpha-clip.ref.png
new file mode 100644
index 0000000..d619b6d
Binary files /dev/null and b/test/reference/recordflip-whole-paint-alpha-clip.ref.png differ
diff --git a/test/reference/recordflip-whole-paint-alpha-solid-clip.ref.png b/test/reference/recordflip-whole-paint-alpha-solid-clip.ref.png
new file mode 100644
index 0000000..10dde68
Binary files /dev/null and b/test/reference/recordflip-whole-paint-alpha-solid-clip.ref.png differ
diff --git a/test/reference/recordflip-whole-paint-alpha.ref.png b/test/reference/recordflip-whole-paint-alpha.ref.png
new file mode 100644
index 0000000..599acfb
Binary files /dev/null and b/test/reference/recordflip-whole-paint-alpha.ref.png differ
diff --git a/test/reference/recordflip-whole-paint.ref.png b/test/reference/recordflip-whole-paint.ref.png
new file mode 100644
index 0000000..22cc7a1
Binary files /dev/null and b/test/reference/recordflip-whole-paint.ref.png differ
diff --git a/test/reference/recordflip-whole-select-font-face.ref.png b/test/reference/recordflip-whole-select-font-face.ref.png
new file mode 100644
index 0000000..eb71085
Binary files /dev/null and b/test/reference/recordflip-whole-select-font-face.ref.png differ
diff --git a/test/reference/recordflip-whole-self-intersecting.ref.png b/test/reference/recordflip-whole-self-intersecting.ref.png
new file mode 100644
index 0000000..d554d83
Binary files /dev/null and b/test/reference/recordflip-whole-self-intersecting.ref.png differ
diff --git a/test/reference/recordflip-whole-text-transform.ref.png b/test/reference/recordflip-whole-text-transform.ref.png
new file mode 100644
index 0000000..31784d7
Binary files /dev/null and b/test/reference/recordflip-whole-text-transform.ref.png differ
commit 7f7ed4c04e49b64c15d60889a8cdc4075efd8236
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Oct 2 09:16:04 2014 +0100

    image: Eliminate self-intersections for the pixman traps compositor
    
    As pixman uses an accumulation mask, it oversamples neighbouring edges
    within a cell. We can reduce the impact of this by eliminating
    overlapping triangles/trapezoids from being passed into pixman.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-image-compositor.c b/src/cairo-image-compositor.c
index 51ffc34..6ff0f09 100644
--- a/src/cairo-image-compositor.c
+++ b/src/cairo-image-compositor.c
@@ -649,11 +649,18 @@ composite_traps (void			*_dst,
 {
     cairo_image_surface_t *dst = (cairo_image_surface_t *) _dst;
     cairo_image_source_t *src = (cairo_image_source_t *) abstract_src;
+    cairo_int_status_t status;
     pixman_image_t *mask;
     pixman_format_code_t format;
 
     TRACE ((stderr, "%s\n", __FUNCTION__));
 
+    /* pixman doesn't eliminate self-intersecting trapezoids/edges */
+    status = _cairo_bentley_ottmann_tessellate_traps (traps,
+						      CAIRO_FILL_RULE_WINDING);
+    if (status != CAIRO_INT_STATUS_SUCCESS)
+	    return status;
+
     /* Special case adding trapezoids onto a mask surface; we want to avoid
      * creating an intermediate temporary mask unnecessarily.
      *
@@ -738,6 +745,31 @@ composite_tristrip (void			*_dst,
     if (strip->num_points < 3)
 	return CAIRO_STATUS_SUCCESS;
 
+    if (1) { /* pixman doesn't eliminate self-intersecting triangles/edges */
+	    cairo_int_status_t status;
+	    cairo_traps_t traps;
+	    int n;
+
+	    _cairo_traps_init (&traps);
+	    for (n = 0; n < strip->num_points; n++) {
+		    cairo_point_t p[4];
+
+		    p[0] = strip->points[0];
+		    p[1] = strip->points[1];
+		    p[2] = strip->points[2];
+		    p[3] = strip->points[0];
+
+		    _cairo_traps_tessellate_convex_quad (&traps, p);
+	    }
+	    status = composite_traps (_dst, op, abstract_src,
+				      src_x, src_y,
+				      dst_x, dst_y,
+				      extents, antialias, &traps);
+	    _cairo_traps_fini (&traps);
+
+	    return status;
+    }
+
     format = antialias == CAIRO_ANTIALIAS_NONE ? PIXMAN_a1 : PIXMAN_a8;
     if (dst->pixman_format == format &&
 	(abstract_src == NULL ||


More information about the cairo-commit mailing list