diff options
author | Adam Jackson <ajax@redhat.com> | 2017-02-24 10:41:08 -0500 |
---|---|---|
committer | Adam Jackson <ajax@redhat.com> | 2017-02-24 11:16:20 -0500 |
commit | 1b6826f326e7159b7464a010b7f4822fa407642d (patch) | |
tree | b1c1658d3b79c140c5fa1213be34c65163ddca46 | |
parent | f8a94ca3b2a32fe01aed86f83a2bf60ac8dc5fc7 (diff) |
mi: "Cache" arc span data for dashed arcsarcology
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.
Back in 946f664b I'd removed a more elaborate LRU cache for arcs. This
change doesn't so much "introduce a cache" as "preserves context".
Signed-off-by: Adam Jackson <ajax@redhat.com>
-rw-r--r-- | mi/miarc.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/mi/miarc.c b/mi/miarc.c index d6be99000..71df4ab64 100644 --- a/mi/miarc.c +++ b/mi/miarc.c @@ -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); |