[Pixman] [PATCH 2/2] pixman_composite_trapezoids(): don't clip to extents for some operators

Søren Sandmann sandmann at cs.au.dk
Fri Oct 12 19:53:18 PDT 2012


From: Søren Sandmann Pedersen <ssp at redhat.com>

pixman_composite_trapezoids() is supposed to composite across the
entire destination, but it actually only composites across the extent
of the trapezoids. For operators such as ADD or OVER this doesn't
matter since a zero source has no effect on the destination. But for
operators such as SRC or IN, it does matter.

So for such operators where a zero source has an effect, don't clip to
the trap extents.
---
 pixman/pixman-trap.c        |   43 +++++++++++++++++++++++++++++++++++--------
 test/composite-traps-test.c |    2 +-
 2 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/pixman/pixman-trap.c b/pixman/pixman-trap.c
index f633738..ab5c8c8 100644
--- a/pixman/pixman-trap.c
+++ b/pixman/pixman-trap.c
@@ -387,12 +387,43 @@ pixman_rasterize_trapezoid (pixman_image_t *          image,
     }
 }
 
+static const pixman_bool_t zero_src_has_no_effect[PIXMAN_N_OPERATORS] =
+{
+    FALSE,	/* Clear		0			0    */
+    FALSE,	/* Src			1			0    */
+    TRUE,	/* Dst			0			1    */
+    TRUE,	/* Over			1			1-Aa */
+    TRUE,	/* OverReverse		1-Ab			1    */
+    FALSE,	/* In			Ab			0    */
+    FALSE,	/* InReverse		0			Aa   */
+    FALSE,	/* Out			1-Ab			0    */
+    TRUE,	/* OutReverse		0			1-Aa */
+    TRUE,	/* Atop			Ab			1-Aa */
+    FALSE,	/* AtopReverse		1-Ab			Aa   */
+    TRUE,	/* Xor			1-Ab			1-Aa */
+    TRUE,	/* Add			1			1    */
+};
+
 static pixman_bool_t
-get_trap_extents (pixman_op_t op, const pixman_trapezoid_t *traps, int n_traps,
+get_trap_extents (pixman_op_t op, pixman_image_t *dest,
+		  const pixman_trapezoid_t *traps, int n_traps,
 		  pixman_box32_t *box)
 {
     int i;
 
+    /* When the operator is such that a zero source has an
+     * effect on the underlying image, we have to
+     * composite across the entire destination
+     */
+    if (!zero_src_has_no_effect [op])
+    {
+	box->x1 = 0;
+	box->y1 = 0;
+	box->x2 = dest->bits.width;
+	box->y2 = dest->bits.height;
+	return TRUE;
+    }
+    
     box->x1 = INT32_MAX;
     box->y1 = INT32_MAX;
     box->x2 = INT32_MIN;
@@ -443,12 +474,8 @@ get_trap_extents (pixman_op_t op, const pixman_trapezoid_t *traps, int n_traps,
  * All the trapezoids are conceptually rendered to an infinitely big image.
  * The (0, 0) coordinates of this image are then aligned with the (x, y)
  * coordinates of the source image, and then both images are aligned with
- * the (x, y) coordinates of the destination. Then, in principle, compositing
- * of these three images takes place across the entire destination.
- *
- * FIXME: However, there is currently a bug, where we restrict this compositing
- * to the bounding box of the trapezoids. This is incorrect for operators such
- * as SRC and IN where blank source pixels do have an effect on the destination.
+ * the (x, y) coordinates of the destination. Then these three images are
+ * composited across the entire destination.
  */
 PIXMAN_EXPORT void
 pixman_composite_trapezoids (pixman_op_t		op,
@@ -491,7 +518,7 @@ pixman_composite_trapezoids (pixman_op_t		op,
 	pixman_box32_t box;
 	int i;
 
-	if (!get_trap_extents (op, traps, n_traps, &box))
+	if (!get_trap_extents (op, dst, traps, n_traps, &box))
 	    return;
 	
 	tmp = pixman_image_create_bits (
diff --git a/test/composite-traps-test.c b/test/composite-traps-test.c
index ff03b50..9fc94a4 100644
--- a/test/composite-traps-test.c
+++ b/test/composite-traps-test.c
@@ -251,6 +251,6 @@ test_composite (int      testnum,
 int
 main (int argc, const char *argv[])
 {
-    return fuzzer_test_main("composite traps", 40000, 0xE3112106,
+    return fuzzer_test_main("composite traps", 40000, 0x33BFAA55,
 			    test_composite, argc, argv);
 }
-- 
1.7.4



More information about the Pixman mailing list