[PATCH 12/13] mi: Fill all spans for PolyFillArc at once
Keith Packard
keithp at keithp.com
Mon May 5 15:02:19 PDT 2014
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 <keithp at keithp.com>
---
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
More information about the xorg-devel
mailing list