A couple of questions

Carl Worth <[email protected]> Tue, 11 Jun 2002 02:21:05 +0000
Newsgroups gmane.comp.xfree86.render
Message-ID <[email protected]>
On Jun 10, Jorge Valencia wrote:
 > Is it possible to have a single call to render multiple polygons (lines) at
 > the same time instead of calling the XRenderCompositeDoublePoly() function
 > for each of the polygons? (something analogous to XDrawSegments() for
 > XSegments).
 > This would avoid the performance penalty of the function call overhead which
 > is considerable when thousand of polygons are redrawn per iteration.

More important than any possible performance improvement:

It's necessary to process multiple polygons simultaneously in order to
correctly render shapes that can't be specified by a single polygon,
(ie. closed line paths including "donuts").

For that reason, I was just about to code up
XRenderCompositeDoublePolys. But I think I'll go to bed instead. I'll
probably get to it early tomorrow morning.

All it needs is a new interface -- the internal tessellation code
should work just fine as is.

It would also be desirable to have the winding parameter actually
work, (eg. cause the tessellation to use the non-zero winding rule
rather than the even-odd rule). The attached patch seems to do the
trick for that.

-Carl


-- 
Carl Worth                                        
USC Information Sciences Institute                 [email protected]
3811 N. Fairfax Dr. #200, Arlington VA 22203		  703-812-3725
polydiff (text/plain, 978 B)
Index: Poly.c
===================================================================
RCS file: /mirrors/xfree86/xc/lib/Xrender/Poly.c,v
retrieving revision 1.7
diff -u -r1.7 Poly.c
--- Poly.c	4 Jun 2002 23:22:36 -0000	1.7
+++ Poly.c	6 Jun 2002 13:08:02 -0000
@@ -93,6 +93,7 @@
     Edge	*active;
     Edge	*e, *en, *next;
     XFixed	y, next_y, intersect;
+    int		in_out;
     
     qsort (edges, nedges, sizeof (Edge), CompareEdge);
     
@@ -189,8 +190,24 @@
 	    next_y = edges[inactive].edge.p1.y;
 	
 	/* walk the list generating trapezoids */
-	for (e = active; e && (en = e->next); e = en->next)
+	in_out = 0;
+	for (e = active; e && (en = e->next); e = e->next)
 	{
+	    if (winding) {
+		if (e->clockWise) {
+		    in_out++;
+		} else {
+		    in_out--;
+		}
+		if (in_out == 0) {
+		    continue;
+		}
+	    } else {
+		in_out++;
+		if (in_out % 2 == 0) {
+		    continue;
+		}
+	    }
 	    traps->top = y;
 	    traps->bottom = next_y;
 	    traps->left = e->edge;