summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Jackson <ajax@redhat.com>2017-02-24 10:41:08 -0500
committerAdam Jackson <ajax@redhat.com>2017-02-24 11:16:20 -0500
commit1b6826f326e7159b7464a010b7f4822fa407642d (patch)
treeb1c1658d3b79c140c5fa1213be34c65163ddca46
parentf8a94ca3b2a32fe01aed86f83a2bf60ac8dc5fc7 (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.c12
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);