[gimp] app: more responsiveness improvements to GimpChunkIterator



commit 91f4c809d8c0ae7366f10fd1d182923370feae4b
Author: Ell <ell_se yahoo com>
Date:   Sat Mar 30 10:01:03 2019 -0400

    app: more responsiveness improvements to GimpChunkIterator
    
    Improve GimpChunkIterator's responsiveness to changes in processing
    speed.

 app/core/gimpchunkiterator.c | 60 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 47 insertions(+), 13 deletions(-)
---
diff --git a/app/core/gimpchunkiterator.c b/app/core/gimpchunkiterator.c
index 793e116278..baa60faf13 100644
--- a/app/core/gimpchunkiterator.c
+++ b/app/core/gimpchunkiterator.c
@@ -42,7 +42,7 @@
 #define DEFAULT_INTERVAL         (1.0 / 15.0) /* seconds */
 
 /* the minimal area to process per iteration */
-#define MIN_AREA_PER_ITERATION   1024
+#define MIN_AREA_PER_ITERATION   4096
 
 /* the maximal ratio between the actual processed area and the target area,
  * above which the current chunk height is readjusted, even in the middle of a
@@ -51,7 +51,7 @@
 #define MAX_AREA_RATIO           2.0
 
 /* the width of the target-area sliding window */
-#define TARGET_AREA_HISTORY_SIZE 5
+#define TARGET_AREA_HISTORY_SIZE 3
 
 
 struct _GimpChunkIterator
@@ -73,9 +73,11 @@ struct _GimpChunkIterator
 
   gint64          iteration_time;
 
-  gdouble         current_area;
-  gdouble         target_area;
+  gint64          last_time;
+  gint            last_area;
 
+  gdouble         target_area;
+  gdouble         target_area_min;
   gdouble         target_area_history[TARGET_AREA_HISTORY_SIZE];
   gint            target_area_history_i;
   gint            target_area_history_n;
@@ -95,6 +97,7 @@ static gboolean   gimp_chunk_iterator_prepare            (GimpChunkIterator   *i
 static void       gimp_chunk_iterator_set_target_area    (GimpChunkIterator   *iter,
                                                           gdouble              target_area);
 static gdouble    gimp_chunk_iterator_get_target_area    (GimpChunkIterator   *iter);
+static void       gimp_chunk_iterator_reset_target_area  (GimpChunkIterator   *iter);
 
 static void       gimp_chunk_iterator_calc_rect          (GimpChunkIterator   *iter,
                                                           GeglRectangle       *rect,
@@ -246,6 +249,8 @@ gimp_chunk_iterator_set_target_area (GimpChunkIterator *iter,
 {
   gdouble target_area_history[TARGET_AREA_HISTORY_SIZE];
 
+  iter->target_area_min = MIN (iter->target_area_min, target_area);
+
   iter->target_area_history[iter->target_area_history_i++] = target_area;
 
   iter->target_area_history_n  = MAX (iter->target_area_history_n,
@@ -264,12 +269,24 @@ gimp_chunk_iterator_set_target_area (GimpChunkIterator *iter,
 static gdouble
 gimp_chunk_iterator_get_target_area (GimpChunkIterator *iter)
 {
-  if (iter->target_area_history_n)
+  if (iter->target_area)
     return iter->target_area;
   else
     return iter->tile_rect.width * iter->tile_rect.height;
 }
 
+static void
+gimp_chunk_iterator_reset_target_area (GimpChunkIterator *iter)
+{
+  if (iter->target_area_history_n)
+    {
+      iter->target_area           = iter->target_area_min;
+      iter->target_area_min       = MAX_CHUNK_WIDTH * MAX_CHUNK_HEIGHT;
+      iter->target_area_history_i = 0;
+      iter->target_area_history_n = 0;
+    }
+}
+
 static void
 gimp_chunk_iterator_calc_rect (GimpChunkIterator *iter,
                                GeglRectangle     *rect,
@@ -280,6 +297,9 @@ gimp_chunk_iterator_calc_rect (GimpChunkIterator *iter,
   gint    offset_x;
   gint    offset_y;
 
+  if (readjust_height)
+    gimp_chunk_iterator_reset_target_area (iter);
+
   target_area = gimp_chunk_iterator_get_target_area (iter);
 
   aspect_ratio = (gdouble) iter->tile_rect.height /
@@ -293,11 +313,12 @@ gimp_chunk_iterator_calc_rect (GimpChunkIterator *iter,
 
   if (readjust_height)
     {
-      rect->height = ceil ((offset_y + sqrt (target_area * aspect_ratio)) /
+      rect->height = RINT ((offset_y + sqrt (target_area * aspect_ratio)) /
                            iter->tile_rect.height)                        *
                      iter->tile_rect.height                               -
                      offset_y;
 
+      rect->height = MAX (rect->height, iter->tile_rect.height);
       rect->height = MIN (rect->height,
                           iter->current_rect.y + iter->current_rect.height -
                           rect->y);
@@ -308,12 +329,13 @@ gimp_chunk_iterator_calc_rect (GimpChunkIterator *iter,
       rect->height = iter->current_height;
     }
 
-  rect->width = ceil ((offset_x + (gdouble) target_area   /
+  rect->width = RINT ((offset_x + (gdouble) target_area   /
                                   (gdouble) rect->height) /
                       iter->tile_rect.width)              *
                 iter->tile_rect.width                     -
                 offset_x;
 
+  rect->width = MAX (rect->width, iter->tile_rect.width);
   rect->width = MIN (rect->width,
                      iter->current_rect.x + iter->current_rect.width -
                      rect->x);
@@ -414,7 +436,8 @@ gimp_chunk_iterator_next (GimpChunkIterator *iter)
 
   iter->iteration_time = g_get_monotonic_time ();
 
-  iter->current_area = 0;
+  iter->last_time = iter->iteration_time;
+  iter->last_area = 0;
 
   return TRUE;
 }
@@ -423,22 +446,27 @@ gboolean
 gimp_chunk_iterator_get_rect (GimpChunkIterator *iter,
                               GeglRectangle     *rect)
 {
+  gint64 time;
+
   g_return_val_if_fail (iter != NULL, FALSE);
   g_return_val_if_fail (rect != NULL, FALSE);
 
   if (! gimp_chunk_iterator_prepare (iter))
     return FALSE;
 
-  if (iter->current_area >= MIN_AREA_PER_ITERATION)
+  time = g_get_monotonic_time ();
+
+  if (iter->last_area >= MIN_AREA_PER_ITERATION)
     {
       gdouble interval;
 
-      interval = (gdouble) (g_get_monotonic_time () - iter->iteration_time) /
-                 G_TIME_SPAN_SECOND;
+      interval = (gdouble) (time - iter->last_time) / G_TIME_SPAN_SECOND;
 
       gimp_chunk_iterator_set_target_area (
         iter,
-        iter->current_area * iter->interval / interval);
+        iter->last_area * iter->interval / interval);
+
+      interval = (gdouble) (time - iter->iteration_time) / G_TIME_SPAN_SECOND;
 
       if (interval > iter->interval)
         return FALSE;
@@ -455,7 +483,12 @@ gimp_chunk_iterator_get_rect (GimpChunkIterator *iter,
       if (rect->width * rect->height >=
           MAX_AREA_RATIO * gimp_chunk_iterator_get_target_area (iter))
         {
+          GeglRectangle old_rect = *rect;
+
           gimp_chunk_iterator_calc_rect (iter, rect, TRUE);
+
+          if (rect->height >= old_rect.height)
+            *rect = old_rect;
         }
     }
 
@@ -485,7 +518,8 @@ gimp_chunk_iterator_get_rect (GimpChunkIterator *iter,
 
   iter->current_x += rect->width;
 
-  iter->current_area += rect->width * rect->height;
+  iter->last_time = time;
+  iter->last_area = rect->width * rect->height;
 
   return TRUE;
 }


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