[gimp] libgimp: improve gimp_progress_update().



commit 708bdf325a788c22f3383814af5ccaa63376c5f4
Author: Jehan <jehan girinstud io>
Date:   Mon Feb 15 21:54:06 2021 +0100

    libgimp: improve gimp_progress_update().
    
    - Do not only check the step width, but also the time interval between 2
      progress calls. No need to run a PDB call, then update the GUI every
      millisecond or so. This would just unecessarily slow down the plug-in
      for updates which the user won't ever see. From my tests, 20 updates
      per second is plenty enough to have the progression look fluid. No
      need for much more.
    - Do not warn anymore on stderr when we drop progress updates. Even if
      just on the unstable builds, such warning is wrong. First because it
      depends on files and machines. Typically a lot of processing could set
      their progress updates relatively to layers. Yet we currently consider
      that 1/256 steps are too small. So what if you have more than 256
      layers? This would make the same code print a warning on big files,
      and none on small files.
      The second reason is that we should not encourage plug-in developers
      to have limited progression updates, but the opposite (progression
      info makes for good feedback), neither should we expect them to
      compute the step size or the time between updates. It's a much saner
      approach to have them only take care about computing relevant update
      steps while our API focuses on filtering these in order to avoid
      overloading the GUI.
      It makes for good progression feedback, sharp GUI while not taking all
      CPU time on it, all this while making it easy on plug-in developers.

 libgimp/gimpprogress.c | 46 ++++++++++++++++++++++++++--------------------
 1 file changed, 26 insertions(+), 20 deletions(-)
---
diff --git a/libgimp/gimpprogress.c b/libgimp/gimpprogress.c
index d54a8d5591..72a9aa8cd7 100644
--- a/libgimp/gimpprogress.c
+++ b/libgimp/gimpprogress.c
@@ -51,6 +51,7 @@ static GimpValueArray * gimp_temp_progress_run  (GimpProcedure        *procedure
 
 static gdouble         gimp_progress_current = 0.0;
 static const gdouble   gimp_progress_step    = (1.0 / 256.0);
+static const gint64    gimp_progress_delay   = 50000; /* 50 millisecond */
 
 
 /*  public functions  */
@@ -264,16 +265,24 @@ gimp_progress_set_text_printf (const gchar *format,
 
 /**
  * gimp_progress_update:
- * @percentage: Percentage of progress completed (in the range from 0.0 to 1.0).
+ * @percentage: Percentage of progress completed (in the range from 0.0
+ *              to 1.0).
  *
  * Updates the progress bar for the current plug-in.
  *
+ * The library will handle over-updating by possibly dropping silently
+ * some updates when they happen too close next to each other (either
+ * time-wise or step-wise).
+ * The caller does not have to take care of this aspect of progression
+ * and can focus on computing relevant progression steps.
+ *
  * Returns: TRUE on success.
  */
 gboolean
 gimp_progress_update (gdouble percentage)
 {
-  gboolean changed;
+  static gint64 last_update = 0;
+  gboolean      changed;
 
   if (percentage <= 0.0)
     {
@@ -287,32 +296,29 @@ gimp_progress_update (gdouble percentage)
     }
   else
     {
-      changed =
-        (fabs (gimp_progress_current - percentage) > gimp_progress_step);
-
-#ifdef GIMP_UNSTABLE
-      if (! changed)
+      if (last_update == 0 ||
+          g_get_monotonic_time () - last_update >= gimp_progress_delay)
         {
-          static gboolean warned = FALSE;
-          static gint     count  = 0;
-
-          count++;
-
-          if (count > 3 && ! warned)
-            {
-              g_printerr ("%s is updating the progress too often\n",
-                          g_get_prgname ());
-              warned = TRUE;
-            }
+          /* If the progression step is too small, better not show it. */
+          changed =
+            (fabs (gimp_progress_current - percentage) > gimp_progress_step);
+        }
+      else
+        {
+          /* Too many changes in a short time interval. */
+          changed = FALSE;
         }
-#endif
     }
 
-  /*  Suppress the update if the change was only marginal.  */
+  /*  Suppress the update if the change was only marginal or progression
+   *  update happens too often. This is not an error, it is just
+   *  unneeded to overload the GUI with constant updates.
+   */
   if (! changed)
     return TRUE;
 
   gimp_progress_current = percentage;
+  last_update = g_get_monotonic_time ();
 
   return _gimp_progress_update (gimp_progress_current);
 }


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