From 31e5a0a393defb8e0534ab1bde29ab23fc04795d Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=B8ren=20Sandmann=20Pedersen?= Date: Fri, 12 Oct 2012 18:34:33 -0400 Subject: [PATCH] pixman_composite_trapezoids(): don't clip to extents for some operators 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); } -- 2.7.4