[chronojump] Cairo graphs much faster: draw now to surface and then copy to drawingarea (instead of drawingarea d



commit 9775e9fa8ecead268d942625985ed5a43eaa5e2a
Author: Xavier de Blas <xaviblas gmail com>
Date:   Mon Mar 14 16:15:24 2022 +0100

    Cairo graphs much faster: draw now to surface and then copy to drawingarea (instead of drawingarea 
directly)

 src/gui/cairo/bars.cs                 | 14 ++++++++------
 src/gui/cairo/generic.cs              | 17 +++++++++++++++++
 src/gui/cairo/jumpsDjOptimalFall.cs   |  4 ++--
 src/gui/cairo/jumpsProfile.cs         |  4 ++--
 src/gui/cairo/jumpsRjFatigue.cs       |  4 ++--
 src/gui/cairo/jumpsRunsEvolution.cs   |  6 +++---
 src/gui/cairo/jumpsWeightFVProfile.cs |  4 ++--
 src/gui/cairo/raceAnalyzer.cs         | 18 +-----------------
 src/gui/cairo/radial.cs               | 12 +++++++-----
 src/gui/cairo/runDoubleContacts.cs    |  9 ++++++---
 src/gui/cairo/xy.cs                   | 18 +++++++++++++-----
 11 files changed, 63 insertions(+), 47 deletions(-)
---
diff --git a/src/gui/cairo/bars.cs b/src/gui/cairo/bars.cs
index 25a59d913..fb16e2e51 100644
--- a/src/gui/cairo/bars.cs
+++ b/src/gui/cairo/bars.cs
@@ -27,6 +27,7 @@ using Cairo;
 public abstract class CairoBars : CairoGeneric
 {
        protected DrawingArea area;
+       protected ImageSurface surface;
        protected int fontHeightForBottomNames;
        protected int marginForBottomNames;
        protected string title;
@@ -260,8 +261,9 @@ public abstract class CairoBars : CairoGeneric
                this.font = font;
                //LogB.Information("Font: " + font);
 
-               //1 create context
-               g = Gdk.CairoHelper.Create (area.GdkWindow);
+               //1 create context from area->surface (see xy.cs)
+                surface = new ImageSurface(Format.RGB24, area.Allocation.Width, area.Allocation.Height);
+                g = new Context (surface);
 
                if(clearDrawingArea)
                {
@@ -674,7 +676,7 @@ public class CairoBars1Series : CairoBars
                if(testsNotFoundMessage != "")
                        writeMessageAtCenter(testsNotFoundMessage);
 
-               endGraphDisposing(g);
+               endGraphDisposing(g, surface, area.GdkWindow);
        }
 
        //regular constructor
@@ -763,7 +765,7 @@ LogB.Information(string.Format("y: {0}, alto: {1}", y, graphHeight -y - bottomMa
 
                writeTitleAtTop ();
 
-               endGraphDisposing(g);
+               endGraphDisposing(g, surface, area.GdkWindow);
        }
 }
 
@@ -788,7 +790,7 @@ public class CairoBarsNHSeries : CairoBars
                LogB.Information("constructor without points, area.GdkWindow is null:" + (area.GdkWindow == 
null).ToString());
                initGraph(font, 1); //.8 to have title at right
 
-               endGraphDisposing(g);
+               endGraphDisposing(g, surface, area.GdkWindow);
        }
 
        //regular constructor
@@ -1043,7 +1045,7 @@ public class CairoBarsNHSeries : CairoBars
                writeTitleAtTop ();
                writeLegend ();
 
-               endGraphDisposing(g);
+               endGraphDisposing(g, surface, area.GdkWindow);
        }
 }
 
diff --git a/src/gui/cairo/generic.cs b/src/gui/cairo/generic.cs
index 81138e8ed..1bf867284 100644
--- a/src/gui/cairo/generic.cs
+++ b/src/gui/cairo/generic.cs
@@ -52,6 +52,23 @@ public abstract class CairoGeneric
                eg. on Linux can do the writeCoordinatesOfMouseClick() without disposing, but on win and mac 
does not work, so dispose always.
         */
 
+       protected void endGraphDisposing(Cairo.Context g, ImageSurface surface, Gdk.Window window)
+       {
+               if(surface != null)
+               {
+                       //using (Context gArea = Gdk.CairoHelper.Create (area.GdkWindow))
+                       using (Context gArea = Gdk.CairoHelper.Create (window))
+                       {
+                               gArea.SetSource (surface);
+                               gArea.Paint ();
+                       }
+
+                       surface.Dispose();
+               }
+
+               g.GetTarget().Dispose ();
+               g.Dispose ();
+       }
        protected void endGraphDisposing(Cairo.Context g)
        {
                g.GetTarget().Dispose ();
diff --git a/src/gui/cairo/jumpsDjOptimalFall.cs b/src/gui/cairo/jumpsDjOptimalFall.cs
index fe2f0c94e..ad413fc43 100644
--- a/src/gui/cairo/jumpsDjOptimalFall.cs
+++ b/src/gui/cairo/jumpsDjOptimalFall.cs
@@ -39,7 +39,7 @@ public class JumpsDjOptimalFallGraph : CairoXY
                printText(area.Allocation.Width /2, area.Allocation.Height /2, 24, textHeight,
                                needToExecuteJumpsStr + " " + jumpType + ".", g, alignTypes.CENTER);
 
-               endGraphDisposing(g);
+               endGraphDisposing(g, surface, area.GdkWindow);
        }
 
        //regular constructor
@@ -103,7 +103,7 @@ public class JumpsDjOptimalFallGraph : CairoXY
                }
                writeTitle();
 
-               endGraphDisposing(g);
+               endGraphDisposing(g, surface, area.GdkWindow);
        }
 
        protected override void writeTitle()
diff --git a/src/gui/cairo/jumpsProfile.cs b/src/gui/cairo/jumpsProfile.cs
index 15e52b109..9b4794599 100644
--- a/src/gui/cairo/jumpsProfile.cs
+++ b/src/gui/cairo/jumpsProfile.cs
@@ -59,7 +59,7 @@ public static class JumpsProfileGraph
                //LogB.Information(string.Format("is area null: {0}", (area == null)));
                //LogB.Information(string.Format("is area.GdkWindow null: {0}", (area.GdkWindow == null)));
 
-               //1 create context
+               //1 create context (TODO: future do it converting to a surface like xy, generic, ...)
                Cairo.Context g = Gdk.CairoHelper.Create (area.GdkWindow);
                
                //2 clear DrawingArea (white)
@@ -176,7 +176,7 @@ public static class JumpsProfileGraph
                        y += 69;
                }
                
-               //10 dispose
+               //10 dispose  (TODO: future do it converting to a surface like xy, generic, ...)
                g.GetTarget().Dispose ();
                g.Dispose ();
        }
diff --git a/src/gui/cairo/jumpsRjFatigue.cs b/src/gui/cairo/jumpsRjFatigue.cs
index 9a169002a..c9cb17a04 100644
--- a/src/gui/cairo/jumpsRjFatigue.cs
+++ b/src/gui/cairo/jumpsRjFatigue.cs
@@ -40,7 +40,7 @@ public class JumpsRjFatigueGraph : CairoXY
                //printText(area.Allocation.Width /2, area.Allocation.Height /2, 24, textHeight,
                //              string.Format("Need to execute jumps: {0}.", jumpType), g, true);
 
-               endGraphDisposing(g);
+               endGraphDisposing(g, surface, area.GdkWindow);
        }
        public JumpsRjFatigueGraph (
                        List<PointF> point_l, double slope, double intercept,
@@ -97,7 +97,7 @@ public class JumpsRjFatigueGraph : CairoXY
 
                writeTitle();
 
-               endGraphDisposing(g);
+               endGraphDisposing(g, surface, area.GdkWindow);
        }
 
        //here X is year, add/subtract third of a year
diff --git a/src/gui/cairo/jumpsRunsEvolution.cs b/src/gui/cairo/jumpsRunsEvolution.cs
index 4385cbc9b..1f261f90f 100644
--- a/src/gui/cairo/jumpsRunsEvolution.cs
+++ b/src/gui/cairo/jumpsRunsEvolution.cs
@@ -43,7 +43,7 @@ public abstract class EvolutionGraph : CairoXY
 
                writeTitle();
 
-               endGraphDisposing(g);
+               endGraphDisposing(g, surface, area.GdkWindow);
        }
 
        //here X is year, add/subtract third of a year
@@ -134,7 +134,7 @@ public class JumpsEvolutionGraph : EvolutionGraph
                printText(area.Allocation.Width /2, area.Allocation.Height /2, 24, textHeight,
                                errorMessage, g, alignTypes.CENTER);
 
-               endGraphDisposing(g);
+               endGraphDisposing(g, surface, area.GdkWindow);
        }
 
        //regular constructor
@@ -180,7 +180,7 @@ public class RunsEvolutionGraph : EvolutionGraph
                printText(area.Allocation.Width /2, area.Allocation.Height /2, 24, textHeight,
                                needToExecuteRunsStr + " " + runType + ".", g, alignTypes.CENTER);
 
-               endGraphDisposing(g);
+               endGraphDisposing(g, surface, area.GdkWindow);
        }
 
        //regular constructor
diff --git a/src/gui/cairo/jumpsWeightFVProfile.cs b/src/gui/cairo/jumpsWeightFVProfile.cs
index 72d4af274..d97d8ccb3 100644
--- a/src/gui/cairo/jumpsWeightFVProfile.cs
+++ b/src/gui/cairo/jumpsWeightFVProfile.cs
@@ -48,7 +48,7 @@ public class JumpsWeightFVProfileGraph : CairoXY
 
                plotError();
 
-               endGraphDisposing(g);
+               endGraphDisposing(g, surface, area.GdkWindow);
        }
 
        //regular constructor
@@ -172,7 +172,7 @@ public class JumpsWeightFVProfileGraph : CairoXY
                if(errorMessage != ErrorAtStart.ALLOK)
                        plotError();
 
-               endGraphDisposing(g);
+               endGraphDisposing(g, surface, area.GdkWindow);
        }
 
        protected override void writeTitle()
diff --git a/src/gui/cairo/raceAnalyzer.cs b/src/gui/cairo/raceAnalyzer.cs
index 9c460490c..d7ea38ace 100644
--- a/src/gui/cairo/raceAnalyzer.cs
+++ b/src/gui/cairo/raceAnalyzer.cs
@@ -33,22 +33,6 @@ public class CairoGraphRaceAnalyzer : CairoXY
        private TwoListsOfDoubles verticalLinesUs_2l;
        private bool useListOfDoublesOnY;
 
-       /*
-       //constructor when there are no points
-       public CairoGraphRaceAnalyzer (DrawingArea area, string jumpType, string font)//, string title, 
string jumpType, string date)
-       {
-               this.area = area;
-
-               initGraph(font);
-
-               g.SetFontSize(16);
-               printText(area.Allocation.Width /2, area.Allocation.Height /2, 24, textHeight,
-                               needToExecuteJumpsStr + " " + jumpType + ".", g, alignTypes.CENTER);
-
-               endGraphDisposing(g);
-       }
-       */
-
        //to avoid to have new data on PassData while the for is working on plotRealPoints
 //     static bool doing;
        //regular constructor
@@ -212,7 +196,7 @@ public class CairoGraphRaceAnalyzer : CairoXY
                                paintVerticalTriggerLine(g, trigger, textHeight -3);
 
                if(initGraphDone)
-                       endGraphDisposing(g);
+                       endGraphDisposing(g, surface, area.GdkWindow);
 
                //doing = false;
        }
diff --git a/src/gui/cairo/radial.cs b/src/gui/cairo/radial.cs
index 1b7c4675a..1cfd39748 100644
--- a/src/gui/cairo/radial.cs
+++ b/src/gui/cairo/radial.cs
@@ -31,6 +31,7 @@ public class CairoRadial : CairoGeneric
        private int margin = 6;
        private int offsetV = 6; //to move the graph vertically
        private Gtk.DrawingArea area;
+       protected ImageSurface surface;
        private double minSide;
        private Cairo.Color black;
        private Cairo.Color colorArrow;
@@ -45,13 +46,14 @@ public class CairoRadial : CairoGeneric
        public void GraphBlank()
        {
                initGraph();
-               endGraphDisposing(g);
+               endGraphDisposing(g, surface, area.GdkWindow);
        }
 
        private void initGraph()
        {
-               //1 create context
-               g = Gdk.CairoHelper.Create (area.GdkWindow);
+               //1 create context from area->surface (see xy.cs)
+                surface = new ImageSurface(Format.RGB24, area.Allocation.Width, area.Allocation.Height);
+                g = new Context (surface);
                
                //2 clear DrawingArea (white)
                g.SetSourceRGB(1,1,1);
@@ -154,7 +156,7 @@ public class CairoRadial : CairoGeneric
                if(speedMax > speed)
                        graphLineFromCenter(speedMax, gray);
 
-               endGraphDisposing(g);
+               endGraphDisposing(g, surface, area.GdkWindow);
        }
 
        //used at end or capture or at load
@@ -180,7 +182,7 @@ public class CairoRadial : CairoGeneric
 
                graphLineFromCenter(speedMax, gray);
 
-               endGraphDisposing(g);
+               endGraphDisposing(g, surface, area.GdkWindow);
        }
 
        private void graphLineFromCenter(double toValue, Cairo.Color color)
diff --git a/src/gui/cairo/runDoubleContacts.cs b/src/gui/cairo/runDoubleContacts.cs
index ebd1ead19..c2df1d684 100644
--- a/src/gui/cairo/runDoubleContacts.cs
+++ b/src/gui/cairo/runDoubleContacts.cs
@@ -27,6 +27,7 @@ using Cairo;
 public class CairoRunDoubleContacts : CairoGeneric
 {
        protected DrawingArea area;
+       protected ImageSurface surface;
        protected Cairo.Context g;
        protected Cairo.Color black;
        protected Cairo.Color colorBackground;
@@ -49,8 +50,9 @@ public class CairoRunDoubleContacts : CairoGeneric
        //from CairoRadial
        protected void initGraph()
        {
-               //1 create context
-               g = Gdk.CairoHelper.Create (area.GdkWindow);
+               //1 create context from area->surface (see xy.cs)
+                surface = new ImageSurface(Format.RGB24, area.Allocation.Width, area.Allocation.Height);
+                g = new Context (surface);
                
                //2 clear DrawingArea (white)
                g.SetSourceRGB(1,1,1);
@@ -134,7 +136,8 @@ public class CairoRunDoubleContacts : CairoGeneric
 
                drawTracks (timeTotal, timeTotalWithExtraPTL, negativePTLTime);
                drawStartAndEnd (timeTotal, timeTotalWithExtraPTL, negativePTLTime);
-               endGraphDisposing(g);
+
+               endGraphDisposing(g, surface, area.GdkWindow);
        }
 
        protected virtual void drawTracks (double timeTotal, double timeTotalWithExtraPTL, double 
negativePTLTime)
diff --git a/src/gui/cairo/xy.cs b/src/gui/cairo/xy.cs
index 7348c5712..441d4c00f 100644
--- a/src/gui/cairo/xy.cs
+++ b/src/gui/cairo/xy.cs
@@ -48,6 +48,7 @@ public abstract class CairoXY : CairoGeneric
        protected double pointsMaxValue;
 
        protected DrawingArea area;
+       protected ImageSurface surface;
        protected string title;
        protected string jumpType;
        protected string runType;
@@ -127,12 +128,20 @@ public abstract class CairoXY : CairoGeneric
 
                totalMargins = outerMargin + innerMargin;
 
-               //1 create context
-               g = Gdk.CairoHelper.Create (area.GdkWindow);
+               // 1 create context
+               /* using drawingarea (slow)
+                  g = Gdk.CairoHelper.Create (area.GdkWindow);
+
+                  //from area->surface (see xy.cs)
+                  //draw on surface: create surface, context related to this surface, draw on this contex
+                  //copy later to drawingarea before disposing, this is much faster
+                */
+               surface = new ImageSurface(Format.RGB24, area.Allocation.Width, area.Allocation.Height);
+               g = new Context (surface);
 
                if(clearDrawingArea)
                {
-                       //2 clear DrawingArea (white)
+                       //2 clear DrawingArea (context) (paint in white)
                        g.SetSourceRGB(1,1,1);
                        g.Paint();
                }
@@ -527,8 +536,7 @@ public abstract class CairoXY : CairoGeneric
                // 1) need to do this because context has been disposed
                LogB.Information(string.Format("g == null: {0}", (g = null)));
                if(g == null)
-                       g = Gdk.CairoHelper.Create (area.GdkWindow);
-
+                       g = Gdk.CairoHelper.Create (area.GdkWindow); //area->surface does not work
 
                int line = 4;
                /*


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]