aboutsummaryrefslogtreecommitdiff
path: root/pixman
diff options
context:
space:
mode:
Diffstat (limited to 'pixman')
-rw-r--r--pixman/configure.ac5
-rw-r--r--pixman/pixman/pixman-bits-image.c54
-rw-r--r--pixman/pixman/pixman-fast-path.c3
-rw-r--r--pixman/pixman/pixman-private.h3
-rw-r--r--pixman/pixman/pixman-trap.c132
-rw-r--r--pixman/pixman/pixman.h5
-rw-r--r--pixman/test/composite-traps-test.c2
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);
}