diff options
Diffstat (limited to 'pixman')
-rw-r--r-- | pixman/configure.ac | 5 | ||||
-rw-r--r-- | pixman/pixman/pixman-bits-image.c | 54 | ||||
-rw-r--r-- | pixman/pixman/pixman-fast-path.c | 3 | ||||
-rw-r--r-- | pixman/pixman/pixman-private.h | 3 | ||||
-rw-r--r-- | pixman/pixman/pixman-trap.c | 132 | ||||
-rw-r--r-- | pixman/pixman/pixman.h | 5 | ||||
-rw-r--r-- | pixman/test/composite-traps-test.c | 2 |
7 files changed, 143 insertions, 61 deletions
diff --git a/pixman/configure.ac b/pixman/configure.ac index c069b483c..f9c0e0276 100644 --- a/pixman/configure.ac +++ b/pixman/configure.ac @@ -89,6 +89,9 @@ AC_DEFUN([PIXMAN_LINK_WITH_ENV],[dnl LDFLAGS="" LIBS="" $1 + CFLAGS="$save_CFLAGS $CFLAGS" + LDFLAGS="$save_LDFLAGS $LDFLAGS" + LIBS="$save_LIBS $LIBS" AC_LINK_IFELSE( [AC_LANG_SOURCE([$2])], [pixman_cc_stderr=`test -f conftest.err && cat conftest.err` @@ -921,8 +924,8 @@ if test $ac_cv_tls = none ; then AC_MSG_CHECKING(for pthread_setspecific) - PIXMAN_CHECK_PTHREAD([CFLAGS="-D_REENTRANT"; LIBS="-lpthread"]) PIXMAN_CHECK_PTHREAD([CFLAGS="-pthread"; LDFLAGS="-pthread"]) + PIXMAN_CHECK_PTHREAD([CFLAGS="-D_REENTRANT"; LIBS="-lpthread"]) PIXMAN_CHECK_PTHREAD([CFLAGS="-D_REENTRANT"; LDFLAGS="-lroot"]) if test $support_for_pthread_setspecific = yes; then diff --git a/pixman/pixman/pixman-bits-image.c b/pixman/pixman/pixman-bits-image.c index 029093ddc..085dd1606 100644 --- a/pixman/pixman/pixman-bits-image.c +++ b/pixman/pixman/pixman-bits-image.c @@ -1388,7 +1388,8 @@ static uint32_t * create_bits (pixman_format_code_t format, int width, int height, - int * rowstride_bytes) + int * rowstride_bytes, + pixman_bool_t clear) { int stride; size_t buf_size; @@ -1420,7 +1421,10 @@ create_bits (pixman_format_code_t format, if (rowstride_bytes) *rowstride_bytes = stride; - return calloc (buf_size, 1); + if (clear) + return calloc (buf_size, 1); + else + return malloc (buf_size); } pixman_bool_t @@ -1429,7 +1433,8 @@ _pixman_bits_image_init (pixman_image_t * image, int width, int height, uint32_t * bits, - int rowstride) + int rowstride, + pixman_bool_t clear) { uint32_t *free_me = NULL; @@ -1437,7 +1442,7 @@ _pixman_bits_image_init (pixman_image_t * image, { int rowstride_bytes; - free_me = bits = create_bits (format, width, height, &rowstride_bytes); + free_me = bits = create_bits (format, width, height, &rowstride_bytes, clear); if (!bits) return FALSE; @@ -1465,12 +1470,13 @@ _pixman_bits_image_init (pixman_image_t * image, return TRUE; } -PIXMAN_EXPORT pixman_image_t * -pixman_image_create_bits (pixman_format_code_t format, - int width, - int height, - uint32_t * bits, - int rowstride_bytes) +static pixman_image_t * +create_bits_image_internal (pixman_format_code_t format, + int width, + int height, + uint32_t * bits, + int rowstride_bytes, + pixman_bool_t clear) { pixman_image_t *image; @@ -1487,7 +1493,8 @@ pixman_image_create_bits (pixman_format_code_t format, return NULL; if (!_pixman_bits_image_init (image, format, width, height, bits, - rowstride_bytes / (int) sizeof (uint32_t))) + rowstride_bytes / (int) sizeof (uint32_t), + clear)) { free (image); return NULL; @@ -1495,3 +1502,28 @@ pixman_image_create_bits (pixman_format_code_t format, return image; } + +/* If bits is NULL, a buffer will be allocated and initialized to 0 */ +PIXMAN_EXPORT pixman_image_t * +pixman_image_create_bits (pixman_format_code_t format, + int width, + int height, + uint32_t * bits, + int rowstride_bytes) +{ + return create_bits_image_internal ( + format, width, height, bits, rowstride_bytes, TRUE); +} + + +/* If bits is NULL, a buffer will be allocated and _not_ initialized */ +PIXMAN_EXPORT pixman_image_t * +pixman_image_create_bits_no_clear (pixman_format_code_t format, + int width, + int height, + uint32_t * bits, + int rowstride_bytes) +{ + return create_bits_image_internal ( + format, width, height, bits, rowstride_bytes, FALSE); +} diff --git a/pixman/pixman/pixman-fast-path.c b/pixman/pixman/pixman-fast-path.c index a12c6cf6f..d95cb4dee 100644 --- a/pixman/pixman/pixman-fast-path.c +++ b/pixman/pixman/pixman-fast-path.c @@ -1296,7 +1296,8 @@ fast_composite_tiled_repeat (pixman_implementation_t *imp, /* Initialize/validate stack-allocated temporary image */ _pixman_bits_image_init (&extended_src_image, src_image->bits.format, - src_width, 1, &extended_src[0], src_stride); + src_width, 1, &extended_src[0], src_stride, + FALSE); _pixman_image_validate (&extended_src_image); info2.src_image = &extended_src_image; diff --git a/pixman/pixman/pixman-private.h b/pixman/pixman/pixman-private.h index dd03a939b..c0a6bc0a5 100644 --- a/pixman/pixman/pixman-private.h +++ b/pixman/pixman/pixman-private.h @@ -283,7 +283,8 @@ _pixman_bits_image_init (pixman_image_t * image, int width, int height, uint32_t * bits, - int rowstride); + int rowstride, + pixman_bool_t clear); pixman_bool_t _pixman_image_fini (pixman_image_t *image); diff --git a/pixman/pixman/pixman-trap.c b/pixman/pixman/pixman-trap.c index 35128ee3d..ab5c8c895 100644 --- a/pixman/pixman/pixman-trap.c +++ b/pixman/pixman/pixman-trap.c @@ -387,18 +387,95 @@ 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, 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; + box->y2 = INT32_MIN; + + for (i = 0; i < n_traps; ++i) + { + const pixman_trapezoid_t *trap = &(traps[i]); + int y1, y2; + + if (!pixman_trapezoid_valid (trap)) + continue; + + y1 = pixman_fixed_to_int (trap->top); + if (y1 < box->y1) + box->y1 = y1; + + y2 = pixman_fixed_to_int (pixman_fixed_ceil (trap->bottom)); + if (y2 > box->y2) + box->y2 = y2; + +#define EXTEND_MIN(x) \ + if (pixman_fixed_to_int ((x)) < box->x1) \ + box->x1 = pixman_fixed_to_int ((x)); +#define EXTEND_MAX(x) \ + if (pixman_fixed_to_int (pixman_fixed_ceil ((x))) > box->x2) \ + box->x2 = pixman_fixed_to_int (pixman_fixed_ceil ((x))); + +#define EXTEND(x) \ + EXTEND_MIN(x); \ + EXTEND_MAX(x); + + EXTEND(trap->left.p1.x); + EXTEND(trap->left.p2.x); + EXTEND(trap->right.p1.x); + EXTEND(trap->right.p2.x); + } + + if (box->x1 >= box->x2 || box->y1 >= box->y2) + return FALSE; + + return TRUE; +} + /* * pixman_composite_trapezoids() * * 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, @@ -439,46 +516,9 @@ pixman_composite_trapezoids (pixman_op_t op, { pixman_image_t *tmp; pixman_box32_t box; - - box.x1 = INT32_MAX; - box.y1 = INT32_MAX; - box.x2 = INT32_MIN; - box.y2 = INT32_MIN; - - for (i = 0; i < n_traps; ++i) - { - const pixman_trapezoid_t *trap = &(traps[i]); - int y1, y2; - - if (!pixman_trapezoid_valid (trap)) - continue; - - y1 = pixman_fixed_to_int (trap->top); - if (y1 < box.y1) - box.y1 = y1; - - y2 = pixman_fixed_to_int (pixman_fixed_ceil (trap->bottom)); - if (y2 > box.y2) - box.y2 = y2; - -#define EXTEND_MIN(x) \ - if (pixman_fixed_to_int ((x)) < box.x1) \ - box.x1 = pixman_fixed_to_int ((x)); -#define EXTEND_MAX(x) \ - if (pixman_fixed_to_int (pixman_fixed_ceil ((x))) > box.x2) \ - box.x2 = pixman_fixed_to_int (pixman_fixed_ceil ((x))); - -#define EXTEND(x) \ - EXTEND_MIN(x); \ - EXTEND_MAX(x); - - EXTEND(trap->left.p1.x); - EXTEND(trap->left.p2.x); - EXTEND(trap->right.p1.x); - EXTEND(trap->right.p2.x); - } - - if (box.x1 >= box.x2 || box.y1 >= box.y2) + int i; + + if (!get_trap_extents (op, dst, traps, n_traps, &box)) return; tmp = pixman_image_create_bits ( diff --git a/pixman/pixman/pixman.h b/pixman/pixman/pixman.h index 1dc167a7a..c8723cf41 100644 --- a/pixman/pixman/pixman.h +++ b/pixman/pixman/pixman.h @@ -757,6 +757,11 @@ pixman_image_t *pixman_image_create_bits (pixman_format_code_t int height, uint32_t *bits, int rowstride_bytes); +pixman_image_t *pixman_image_create_bits_no_clear (pixman_format_code_t format, + int width, + int height, + uint32_t * bits, + int rowstride_bytes); /* Destructor */ pixman_image_t *pixman_image_ref (pixman_image_t *image); diff --git a/pixman/test/composite-traps-test.c b/pixman/test/composite-traps-test.c index ff03b50d9..9fc94a4d6 100644 --- a/pixman/test/composite-traps-test.c +++ b/pixman/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); } |