This allocates span data for all of the provided arcs and draws the whole set in one call, rather than doing them one at a time. For modern hardware, this is a significant performance improvement.
Signed-off-by: Keith Packard <[email protected]> --- mi/mifillarc.c | 98 ++++++++++++++++++++-------------------------------------- 1 file changed, 34 insertions(+), 64 deletions(-) diff --git a/mi/mifillarc.c b/mi/mifillarc.c index 337343d..1695121 100644 --- a/mi/mifillarc.c +++ b/mi/mifillarc.c @@ -476,26 +476,16 @@ miFillArcSliceSetup(xArc * arc, miArcSliceRec * slice, GCPtr pGC) *wids++ = slw; \ } -static void -miFillEllipseI(DrawablePtr pDraw, GCPtr pGC, xArc * arc) +static int +miFillEllipseI(DrawablePtr pDraw, GCPtr pGC, xArc * arc, DDXPointPtr points, int *widths) { int x, y, e; int yk, xk, ym, xm, dx, dy, xorg, yorg; int slw; miFillArcRec info; - DDXPointPtr points; DDXPointPtr pts; - int *widths; int *wids; - points = malloc(sizeof(DDXPointRec) * arc->height); - if (!points) - return; - widths = malloc(sizeof(int) * arc->height); - if (!widths) { - free(points); - return; - } miFillArcSetup(arc, &info); MIFILLARCSETUP(); if (pGC->miTranslate) { @@ -508,31 +498,19 @@ miFillEllipseI(DrawablePtr pDraw, GCPtr pGC, xArc * arc) MIFILLARCSTEP(slw); ADDSPANS(); } - (*pGC->ops->FillSpans) (pDraw, pGC, pts - points, points, widths, FALSE); - free(widths); - free(points); + return pts - points; } -static void -miFillEllipseD(DrawablePtr pDraw, GCPtr pGC, xArc * arc) +static int +miFillEllipseD(DrawablePtr pDraw, GCPtr pGC, xArc * arc, DDXPointPtr points, int *widths) { int x, y; int xorg, yorg, dx, dy, slw; double e, yk, xk, ym, xm; miFillArcDRec info; - DDXPointPtr points; DDXPointPtr pts; - int *widths; int *wids; - points = malloc(sizeof(DDXPointRec) * arc->height); - if (!points) - return; - widths = malloc(sizeof(int) * arc->height); - if (!widths) { - free(points); - return; - } miFillArcDSetup(arc, &info); MIFILLARCSETUP(); if (pGC->miTranslate) { @@ -545,9 +523,7 @@ miFillEllipseD(DrawablePtr pDraw, GCPtr pGC, xArc * arc) MIFILLARCSTEP(slw); ADDSPANS(); } - (*pGC->ops->FillSpans) (pDraw, pGC, pts - points, points, widths, FALSE); - free(widths); - free(points); + return pts - points; } #define ADDSPAN(l,r) \ @@ -572,17 +548,15 @@ miFillEllipseD(DrawablePtr pDraw, GCPtr pGC, xArc * arc) ADDSPAN(xl, xc); \ } -static void -miFillArcSliceI(DrawablePtr pDraw, GCPtr pGC, xArc * arc) +static int +miFillArcSliceI(DrawablePtr pDraw, GCPtr pGC, xArc * arc, DDXPointPtr points, int *widths) { int yk, xk, ym, xm, dx, dy, xorg, yorg, slw; int x, y, e; miFillArcRec info; miArcSliceRec slice; int ya, xl, xr, xc; - DDXPointPtr points; DDXPointPtr pts; - int *widths; int *wids; miFillArcSetup(arc, &info); @@ -591,14 +565,6 @@ miFillArcSliceI(DrawablePtr pDraw, GCPtr pGC, xArc * arc) slw = arc->height; if (slice.flip_top || slice.flip_bot) slw += (arc->height >> 1) + 1; - points = malloc(sizeof(DDXPointRec) * slw); - if (!points) - return; - widths = malloc(sizeof(int) * slw); - if (!widths) { - free(points); - return; - } if (pGC->miTranslate) { xorg += pDraw->x; yorg += pDraw->y; @@ -622,13 +588,11 @@ miFillArcSliceI(DrawablePtr pDraw, GCPtr pGC, xArc * arc) ADDSLICESPANS(slice.flip_bot); } } - (*pGC->ops->FillSpans) (pDraw, pGC, pts - points, points, widths, FALSE); - free(widths); - free(points); + return pts - points; } -static void -miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc) +static int +miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc, DDXPointPtr points, int *widths) { int x, y; int dx, dy, xorg, yorg, slw; @@ -636,9 +600,7 @@ miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc) miFillArcDRec info; miArcSliceRec slice; int ya, xl, xr, xc; - DDXPointPtr points; DDXPointPtr pts; - int *widths; int *wids; miFillArcDSetup(arc, &info); @@ -647,14 +609,6 @@ miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc) slw = arc->height; if (slice.flip_top || slice.flip_bot) slw += (arc->height >> 1) + 1; - points = malloc(sizeof(DDXPointRec) * slw); - if (!points) - return; - widths = malloc(sizeof(int) * slw); - if (!widths) { - free(points); - return; - } if (pGC->miTranslate) { xorg += pDraw->x; yorg += pDraw->y; @@ -678,9 +632,7 @@ miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc) ADDSLICESPANS(slice.flip_bot); } } - (*pGC->ops->FillSpans) (pDraw, pGC, pts - points, points, widths, FALSE); - free(widths); - free(points); + return pts - points; } /* MIPOLYFILLARC -- The public entry for the PolyFillArc request. @@ -692,21 +644,39 @@ miPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs) { int i; xArc *arc; + int nspans = 0; + DDXPointPtr pts, points; + int *wids, *widths; + int n; + + for (i = narcs, arc = parcs; --i >= 0; arc++) + nspans += arc->height; + + pts = points = malloc (sizeof (DDXPointRec) * nspans + sizeof(int) * nspans); + if (!points) + return; + wids = widths = (int *) (points + nspans); for (i = narcs, arc = parcs; --i >= 0; arc++) { if (miFillArcEmpty(arc)) continue; if ((arc->angle2 >= FULLCIRCLE) || (arc->angle2 <= -FULLCIRCLE)) { if (miCanFillArc(arc)) - miFillEllipseI(pDraw, pGC, arc); + n = miFillEllipseI(pDraw, pGC, arc, pts, wids); else - miFillEllipseD(pDraw, pGC, arc); + n = miFillEllipseD(pDraw, pGC, arc, pts, wids); } else { if (miCanFillArc(arc)) - miFillArcSliceI(pDraw, pGC, arc); + n = miFillArcSliceI(pDraw, pGC, arc, pts, wids); else - miFillArcSliceD(pDraw, pGC, arc); + n = miFillArcSliceD(pDraw, pGC, arc, pts, wids); } + pts += n; + wids += n; } + nspans = pts - points; + if (nspans) + (*pGC->ops->FillSpans) (pDraw, pGC, nspans, points, widths, FALSE); + free (points); } -- 2.0.0.rc0 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
