[PATCH 5/6] Optimize adding opaque trapezoids onto a8 destination.

Søren Sandmann Pedersen sandmann at cs.au.dk
Fri Feb 11 06:54:17 PST 2011


From: Søren Sandmann Pedersen <ssp at redhat.com>

When the source is opaque and the destination is alpha only, we can
avoid the temporary mask and just add the trapezoids directly.
---
 pixman/pixman-trap.c |  133 ++++++++++++++++++++++++++++---------------------
 1 files changed, 76 insertions(+), 57 deletions(-)

diff --git a/pixman/pixman-trap.c b/pixman/pixman-trap.c
index 2675773..adf822c 100644
--- a/pixman/pixman-trap.c
+++ b/pixman/pixman-trap.c
@@ -399,10 +399,7 @@ pixman_composite_trapezoids (pixman_op_t		op,
 			     int			n_traps,
 			     const pixman_trapezoid_t *	traps)
 {
-    pixman_image_t *tmp;
-    pixman_box32_t box;
     int i;
-    int x_rel, y_rel;
 
     if (n_traps <= 0)
 	return;
@@ -410,68 +407,90 @@ pixman_composite_trapezoids (pixman_op_t		op,
     _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)
+    if (op == PIXMAN_OP_ADD &&
+	(src->common.flags & FAST_PATH_IS_OPAQUE)		&&
+	(mask_format == dst->common.extended_format_code)	&&
+	!(dst->common.have_clip_region))
     {
-	const pixman_trapezoid_t *trap = &(traps[i]);
-	int y1, y2;
-
-	if (!pixman_trapezoid_valid (trap))
-	    continue;
+	for (i = 0; i < n_traps; ++i)
+	{
+	    const pixman_trapezoid_t *trap = &(traps[i]);
+	    
+	    if (!pixman_trapezoid_valid (trap))
+		continue;
+	    
+	    pixman_rasterize_trapezoid (dst, trap, 0, 0);
+	}
+    }
+    else
+    {
+	pixman_image_t *tmp;
+	pixman_box32_t box;
+	int x_rel, y_rel;
 	
-	y1 = pixman_fixed_to_int (trap->top);
-	if (y1 < box.y1)
-	    box.y1 = y1;
+	box.x1 = INT32_MAX;
+	box.y1 = INT32_MAX;
+	box.x2 = INT32_MIN;
+	box.y2 = INT32_MIN;
 	
-	y2 = pixman_fixed_to_int (pixman_fixed_ceil (trap->bottom));
-	if (y2 > box.y2)
-	    box.y2 = y2;
-
+	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));
+	    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)));
-
+	    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);
+	    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);
+	}
 	
-    for (i = 0; i < n_traps; ++i)
-    {
-	const pixman_trapezoid_t *trap = &(traps[i]);
-
-	if (!pixman_trapezoid_valid (trap))
-	    continue;
-
-	pixman_rasterize_trapezoid (tmp, trap, - box.x1, - box.y1);
+	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)
+	{
+	    const 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);
     }
-
-    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);
 }
 
 static int
-- 
1.7.3.1



More information about the xorg-devel mailing list