pixman: Branch 'master' - 3 commits

Søren Sandmann Pedersen sandmann at kemper.freedesktop.org
Sun Oct 21 01:18:38 PDT 2012


 pixman/pixman-bits-image.c  |   54 ++++++++++++++----
 pixman/pixman-fast-path.c   |    3 -
 pixman/pixman-private.h     |    3 -
 pixman/pixman-trap.c        |  132 ++++++++++++++++++++++++++++----------------
 pixman/pixman.h             |    5 +
 test/composite-traps-test.c |    2 
 6 files changed, 139 insertions(+), 60 deletions(-)

New commits:
commit 31e5a0a393defb8e0534ab1bde29ab23fc04795d
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Fri Oct 12 18:34:33 2012 -0400

    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.

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);
 }
commit 65db2362e2793a527c2e831cceb81d8d6ad51b8f
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Fri Oct 12 18:29:56 2012 -0400

    pixman_composite_trapezoids(): Factor out extents computation
    
    The computation of the extents rectangle is moved to its own
    function.

diff --git a/pixman/pixman-trap.c b/pixman/pixman-trap.c
index 35128ee..f633738 100644
--- a/pixman/pixman-trap.c
+++ b/pixman/pixman-trap.c
@@ -387,6 +387,56 @@ pixman_rasterize_trapezoid (pixman_image_t *          image,
     }
 }
 
+static pixman_bool_t
+get_trap_extents (pixman_op_t op, const pixman_trapezoid_t *traps, int n_traps,
+		  pixman_box32_t *box)
+{
+    int i;
+
+    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()
  *
@@ -439,46 +489,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, traps, n_traps, &box))
 	    return;
 	
 	tmp = pixman_image_create_bits (
commit 2d9cb563b415e90cef898de03de7ed9c6f091db1
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Fri Oct 12 18:07:29 2012 -0400

    Add new pixman_image_create_bits_no_clear() API
    
    When pixman_image_create_bits() function is given NULL for bits, it
    will allocate a new buffer and initialize it to zero. However, in some
    cases, only a small region of the image is actually used; in that case
    it is wasteful to touch all of the memory.
    
    The new pixman_image_create_bits_no_clear() works exactly like
    _create_bits() except that it doesn't initialize any newly allocated
    memory.

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 029093d..085dd16 100644
--- a/pixman/pixman-bits-image.c
+++ b/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-fast-path.c b/pixman/pixman-fast-path.c
index a12c6cf..d95cb4d 100644
--- a/pixman/pixman-fast-path.c
+++ b/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-private.h b/pixman/pixman-private.h
index dd03a93..c0a6bc0 100644
--- a/pixman/pixman-private.h
+++ b/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.h b/pixman/pixman.h
index 1dc167a..c8723cf 100644
--- a/pixman/pixman.h
+++ b/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);


More information about the xorg-commit mailing list