[cairo-commit] 2 commits - src/cairo-fixed-private.h src/cairo-xlib-surface.c test/Makefile.sources test/xcomposite-projection.c test/xcomposite-projection.ref.png

Benjamin Otte company at kemper.freedesktop.org
Wed Nov 4 02:20:59 PST 2009


 src/cairo-fixed-private.h          |    9 ++++
 src/cairo-xlib-surface.c           |   22 +++++-----
 test/Makefile.sources              |    1 
 test/xcomposite-projection.c       |   81 +++++++++++++++++++++++++++++++++++++
 test/xcomposite-projection.ref.png |binary
 5 files changed, 102 insertions(+), 11 deletions(-)

New commits:
commit 52afe9c77f2f54372fefeca50321a27e8dda0f63
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Nov 4 11:15:57 2009 +0100

    [xlib] Fix new Composite test
    
    When the reference point was tirggering _line_exceeds_16_16() and got
    adjusted, the code failed to compute the srcX and srcY arguments for the
    call to XRenderCompositeTrapezoids() correctly and caused the resulting
    source image to be misaligned.

diff --git a/src/cairo-fixed-private.h b/src/cairo-fixed-private.h
index e3add4a..68fa577 100644
--- a/src/cairo-fixed-private.h
+++ b/src/cairo-fixed-private.h
@@ -217,6 +217,15 @@ _cairo_fixed_16_16_from_double (double d)
 #endif
 }
 
+static inline int
+_cairo_fixed_16_16_floor (cairo_fixed_t f)
+{
+    if (f >= 0)
+        return f >> 16;
+    else
+        return -((-f - 1) >> 16) - 1;
+}
+
 #if CAIRO_FIXED_BITS == 32
 
 static inline cairo_fixed_t
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 03053f0..fc235a9 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -2605,17 +2605,6 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t	op,
 	break;
     }
 
-    if (traps[0].left.p1.y < traps[0].left.p2.y) {
-	render_reference_x = _cairo_fixed_integer_floor (traps[0].left.p1.x);
-	render_reference_y = _cairo_fixed_integer_floor (traps[0].left.p1.y);
-    } else {
-	render_reference_x = _cairo_fixed_integer_floor (traps[0].left.p2.x);
-	render_reference_y = _cairo_fixed_integer_floor (traps[0].left.p2.y);
-    }
-
-    render_src_x = src_x + render_reference_x - dst_x;
-    render_src_y = src_y + render_reference_y - dst_y;
-
     status = _cairo_xlib_surface_set_clip_region (dst, clip_region);
     if (unlikely (status))
 	goto BAIL;
@@ -2674,6 +2663,17 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t	op,
 	}
     }
 
+    if (xtraps[0].left.p1.y < xtraps[0].left.p2.y) {
+	render_reference_x = _cairo_fixed_16_16_floor (xtraps[0].left.p1.x);
+	render_reference_y = _cairo_fixed_16_16_floor (xtraps[0].left.p1.y);
+    } else {
+	render_reference_x = _cairo_fixed_16_16_floor (xtraps[0].left.p2.x);
+	render_reference_y = _cairo_fixed_16_16_floor (xtraps[0].left.p2.y);
+    }
+
+    render_src_x = src_x + render_reference_x - dst_x;
+    render_src_y = src_y + render_reference_y - dst_y;
+
     XRenderCompositeTrapezoids (dst->dpy,
 				_render_operator (op),
 				src->src_picture, dst->dst_picture,
commit 84bbf179c375622d2c7b4e21b1b8ce189b5a18f2
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Nov 4 11:06:57 2009 +0100

    [test] Add a test exposing bugs in XRenderComposite
    
    This test fills a slightly rotated surface slightly above the 0 line.
    This hits some corner cases in the XRenderComposite path.
    I discovered these issues while playing with video rendering onto the
    canvas in HTML5 (both Webkit and Mozilla have this problem).
    I used CAIRO_ANTIALIAS_NONE and a single-color source in the test to get
    rid of aliasing issues in the output images. This makes some issues
    slightly less visible, but still fails for all of them. If you want to
    get a clearer view, disable it and use romedalen.png instead - it has
    the same size as the red surface.
    
    (At least) 3 bugs are at work here:
    - if _line_exceeds_16_16() triggers for the reference point, the
      source surface will be misaligned.
    - the intel driver seems to have an off-by-one bug on my i945 when
      positioning the source surface, causing black seams at the top
      (not visible in the test unless using romedalen.png) and on the left
      of the image.
    - My Xvfb fails completely in picture up/download in the xlib-fallback
      path.

diff --git a/test/Makefile.sources b/test/Makefile.sources
index f9c2acb..82c761b 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -233,6 +233,7 @@ test_sources = \
 	user-font-mask.c				\
 	user-font-proxy.c				\
 	user-font-rescale.c				\
+	xcomposite-projection.c				\
 	zero-alpha.c
 
 pthread_test_sources = pthread-show-text.c
diff --git a/test/xcomposite-projection.c b/test/xcomposite-projection.c
new file mode 100644
index 0000000..2beb661
--- /dev/null
+++ b/test/xcomposite-projection.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2009 Benjamin Otte
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Kai-Uwe Behrmann not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Kai-Uwe Behrmann makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * BENJAMIN OTTE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL KAI_UWE BEHRMANN BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Benjamin Otte <otte at gnome.org>
+ */
+
+#include "cairo-test.h"
+
+static const char png_filename[] = "romedalen.png";
+
+static cairo_surface_t *
+get_red_surface (void)
+{
+  cairo_surface_t *surface;
+  cairo_t *cr;
+  
+  surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 256, 192);
+  
+  cr = cairo_create (surface);
+  cairo_set_source_rgb (cr, 0.75, 0.25, 0.25);
+  cairo_paint (cr);
+  cairo_destroy (cr);
+
+  return surface;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+    cairo_surface_t *image;
+
+    image = get_red_surface ();
+
+    /* we don't want to debug antialiasing artifacts */
+    cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+
+    /* dark grey background */
+    cairo_set_source_rgb (cr, 0.25, 0.25, 0.25);
+    cairo_paint (cr);
+
+    /* magic transform */
+    cairo_translate (cr, 10, -40);
+    cairo_rotate (cr, -0.05);
+
+    /* place the image on our surface */
+    cairo_set_source_surface (cr, image, 0, 0);
+
+    /* paint the image */
+    cairo_rectangle (cr, 0, 0, cairo_image_surface_get_width (image), cairo_image_surface_get_height (image));
+    cairo_fill (cr);
+
+    cairo_surface_destroy (image);
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (xcomposite_projection,
+	    "Test a bug with XRenderComposite reference computation when projecting the first trapezoid onto 16.16 space",
+	    "xlib", /* keywords */
+	    NULL, /* requirements */
+	    300, 150,
+	    NULL, draw)
diff --git a/test/xcomposite-projection.ref.png b/test/xcomposite-projection.ref.png
new file mode 100644
index 0000000..ea4dddf
Binary files /dev/null and b/test/xcomposite-projection.ref.png differ


More information about the cairo-commit mailing list