[PATCH 1/3] Add pixman_composite_trapezoids().

Søren Sandmann Pedersen ssp at redhat.com
Wed Jan 12 05:49:11 PST 2011


This function is an implementation of the X server request
Trapezoids. That request is what the X backend of cairo is using all
the time; by moving it into pixman we can hopefully make it faster.
---
 pixman/pixman-trap.c |   87 ++++++++++++++++++++++++++++++++++++++++++++++++++
 pixman/pixman.h      |   12 ++++++-
 2 files changed, 98 insertions(+), 1 deletions(-)

diff --git a/pixman/pixman-trap.c b/pixman/pixman-trap.c
index 8353992..a924326 100644
--- a/pixman/pixman-trap.c
+++ b/pixman/pixman-trap.c
@@ -390,3 +390,90 @@ pixman_rasterize_trapezoid (pixman_image_t *          image,
 	pixman_rasterize_edges (image, &l, &r, t, b);
     }
 }
+
+PIXMAN_EXPORT void
+pixman_composite_trapezoids (pixman_op_t		op,
+			     pixman_image_t *		src,
+			     pixman_image_t *		dst,
+			     pixman_format_code_t	mask_format,
+			     int			x_src,
+			     int			y_src,
+			     int			x_dst,
+			     int			y_dst,
+			     int			n_traps,
+			     pixman_trapezoid_t *	traps)
+{
+    pixman_image_t *tmp;
+    pixman_box32_t box;
+    int i;
+    int x_rel, y_rel;
+
+    if (n_traps <= 0)
+	return;
+
+    _pixman_image_validate (src);
+    _pixman_image_validate (dst);
+
+    box.x1 = INT32_MAX;
+    box.y1 = INT32_MAX;
+    box.x2 = INT32_MIN;
+    box.y2 = INT32_MIN;
+    
+    for (i = 0; i < n_traps; ++i)
+    {
+	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;
+    
+    tmp = pixman_image_create_bits (
+	mask_format, box.x2 - box.x1, box.y2 - box.y1, NULL, -1);
+	
+    for (i = 0; i < n_traps; ++i)
+    {
+	pixman_trapezoid_t *trap = &(traps[i]);
+
+	if (!pixman_trapezoid_valid (trap))
+	    continue;
+
+	pixman_rasterize_trapezoid (tmp, trap, - box.x1, - box.y1);
+    }
+
+    x_rel = box.x1 + x_src - x_dst;
+    y_rel = box.y1 + y_src - y_dst;
+
+    pixman_image_composite (op, src, tmp, dst,
+			    x_rel, y_rel, 0, 0, box.x1, box.y1,
+			    box.x2 - box.x1, box.y2 - box.y1);
+
+    pixman_image_unref (tmp);
+}
diff --git a/pixman/pixman.h b/pixman/pixman.h
index b95d0e9..c2f7da3 100644
--- a/pixman/pixman.h
+++ b/pixman/pixman.h
@@ -950,7 +950,17 @@ void           pixman_rasterize_trapezoid  (pixman_image_t            *image,
 					    const pixman_trapezoid_t  *trap,
 					    int                        x_off,
 					    int                        y_off);
-
+void          pixman_composite_trapezoids (pixman_op_t		       op,
+					   pixman_image_t *	       src,
+					   pixman_image_t *	       dst,
+					   pixman_format_code_t	       mask_format,
+					   int			       x_src,
+					   int			       y_src,
+					   int			       x_dst,
+					   int			       y_dst,
+					   int			       n_traps,
+					   pixman_trapezoid_t *	       traps);
+    
 PIXMAN_END_DECLS
 
 #endif /* PIXMAN_H__ */
-- 
1.7.3.1



More information about the xorg-devel mailing list