miarc: "Cache" arc span data for dashed arcs

This avoids recomputing the span data for every dash. x11perf thinks
this is a pretty modest speedup:

    832919.4       840471.1 ( 1.009)   100-pixel dashed ellipse
    672353.1       680652.2 ( 1.012)   100-pixel double-dashed ellipse
     13748.9        24287.9 ( 1.767)   100-pixel wide dashed ellipse
      9236.3        21298.2 ( 2.306)   100-pixel wide double-dashed ellipse

But part of the reason it's so modest there is that the arcs are
relatively small (100 pixel diameter at line width 10, so ~6000 pixels)
and the dashes relatively large (30 on 20 off so ~6 dashes per
quadrant).

With larger arcs and finer dashes this is much more impressive. A fairly
trivial testcase of a single 15000x13000 arc with the default {2, 2}
dash pattern drops from ~3500 milliseconds to 10 milliseconds.

Reviewed-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Adam Jackson <ajax@redhat.com>
This commit is contained in:
Adam Jackson 2017-03-01 16:13:59 -05:00
parent 849c825855
commit 0d7f05ed99
1 changed files with 11 additions and 1 deletions

View File

@ -1021,6 +1021,7 @@ miWideArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
join[0] = join[1] = 0;
for (iphase = (pGC->lineStyle == LineDoubleDash); iphase >= 0; iphase--) {
miArcSpanData *spdata = NULL;
xArc lastArc;
ChangeGCVal gcval;
if (iphase == 1) {
@ -1037,10 +1038,17 @@ miWideArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
miArcDataPtr arcData;
arcData = &polyArcs[iphase].arcs[i];
if (spdata) {
if (lastArc.width != arcData->arc.width ||
lastArc.height != arcData->arc.height) {
free(spdata);
spdata = NULL;
}
}
memcpy(&lastArc, &arcData->arc, sizeof(xArc));
spdata = miArcSegment(pDrawTo, pGCTo, arcData->arc,
&arcData->bounds[RIGHT_END],
&arcData->bounds[LEFT_END], spdata);
free(spdata);
if (polyArcs[iphase].arcs[i].render) {
fillSpans(pDrawTo, pGCTo);
/* don't cap self-joining arcs */
@ -1097,6 +1105,8 @@ miWideArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
}
}
}
free(spdata);
spdata = NULL;
}
miFreeArcs(polyArcs, pGC);