From 0d7f05ed99b71a4641415c9f26e245c3bb24a9a0 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Wed, 1 Mar 2017 16:13:59 -0500 Subject: [PATCH 3/3] 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 Signed-off-by: Adam Jackson --- mi/miarc.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) 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); -- 2.12.0