Blame SOURCES/0003-miarc-Cache-arc-span-data-for-dashed-arcs.patch

a3e08e
From 0d7f05ed99b71a4641415c9f26e245c3bb24a9a0 Mon Sep 17 00:00:00 2001
a3e08e
From: Adam Jackson <ajax@redhat.com>
a3e08e
Date: Wed, 1 Mar 2017 16:13:59 -0500
a3e08e
Subject: [PATCH 3/3] miarc: "Cache" arc span data for dashed arcs
a3e08e
a3e08e
This avoids recomputing the span data for every dash. x11perf thinks
a3e08e
this is a pretty modest speedup:
a3e08e
a3e08e
    832919.4       840471.1 ( 1.009)   100-pixel dashed ellipse
a3e08e
    672353.1       680652.2 ( 1.012)   100-pixel double-dashed ellipse
a3e08e
     13748.9        24287.9 ( 1.767)   100-pixel wide dashed ellipse
a3e08e
      9236.3        21298.2 ( 2.306)   100-pixel wide double-dashed ellipse
a3e08e
a3e08e
But part of the reason it's so modest there is that the arcs are
a3e08e
relatively small (100 pixel diameter at line width 10, so ~6000 pixels)
a3e08e
and the dashes relatively large (30 on 20 off so ~6 dashes per
a3e08e
quadrant).
a3e08e
a3e08e
With larger arcs and finer dashes this is much more impressive. A fairly
a3e08e
trivial testcase of a single 15000x13000 arc with the default {2, 2}
a3e08e
dash pattern drops from ~3500 milliseconds to 10 milliseconds.
a3e08e
a3e08e
Reviewed-by: Keith Packard <keithp@keithp.com>
a3e08e
Signed-off-by: Adam Jackson <ajax@redhat.com>
a3e08e
---
a3e08e
 mi/miarc.c | 12 +++++++++++-
a3e08e
 1 file changed, 11 insertions(+), 1 deletion(-)
a3e08e
a3e08e
diff --git a/mi/miarc.c b/mi/miarc.c
a3e08e
index d6be99000..71df4ab64 100644
a3e08e
--- a/mi/miarc.c
a3e08e
+++ b/mi/miarc.c
a3e08e
@@ -1021,6 +1021,7 @@ miWideArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
a3e08e
     join[0] = join[1] = 0;
a3e08e
     for (iphase = (pGC->lineStyle == LineDoubleDash); iphase >= 0; iphase--) {
a3e08e
         miArcSpanData *spdata = NULL;
a3e08e
+        xArc lastArc;
a3e08e
         ChangeGCVal gcval;
a3e08e
 
a3e08e
         if (iphase == 1) {
a3e08e
@@ -1037,10 +1038,17 @@ miWideArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
a3e08e
             miArcDataPtr arcData;
a3e08e
 
a3e08e
             arcData = &polyArcs[iphase].arcs[i];
a3e08e
+            if (spdata) {
a3e08e
+                if (lastArc.width != arcData->arc.width ||
a3e08e
+                    lastArc.height != arcData->arc.height) {
a3e08e
+                    free(spdata);
a3e08e
+                    spdata = NULL;
a3e08e
+                }
a3e08e
+            }
a3e08e
+            memcpy(&lastArc, &arcData->arc, sizeof(xArc));
a3e08e
             spdata = miArcSegment(pDrawTo, pGCTo, arcData->arc,
a3e08e
                                   &arcData->bounds[RIGHT_END],
a3e08e
                                   &arcData->bounds[LEFT_END], spdata);
a3e08e
-            free(spdata);
a3e08e
             if (polyArcs[iphase].arcs[i].render) {
a3e08e
                 fillSpans(pDrawTo, pGCTo);
a3e08e
                 /* don't cap self-joining arcs */
a3e08e
@@ -1097,6 +1105,8 @@ miWideArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
a3e08e
                 }
a3e08e
             }
a3e08e
         }
a3e08e
+        free(spdata);
a3e08e
+        spdata = NULL;
a3e08e
     }
a3e08e
     miFreeArcs(polyArcs, pGC);
a3e08e
 
a3e08e
-- 
a3e08e
2.12.0
a3e08e