[babl] babl: free LUTs that have been unused for more than 5 minutes



commit a281849c29c407c69dc1f6cc8513c9e5b92a428b
Author: Øyvind Kolås <pippin gimp org>
Date:   Mon Jan 24 03:56:09 2022 +0100

    babl: free LUTs that have been unused for more than 5 minutes

 babl/babl-fish-path.c  | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++
 babl/babl-fish.h       |  1 +
 babl/base/model-gray.c |  1 -
 3 files changed, 57 insertions(+), 1 deletion(-)
---
diff --git a/babl/babl-fish-path.c b/babl/babl-fish-path.c
index 52e89a4..5660b37 100644
--- a/babl/babl-fish-path.c
+++ b/babl/babl-fish-path.c
@@ -317,6 +317,9 @@ int
 _babl_fish_path_destroy (void *data)
 {
   Babl *babl=data;
+  if (babl->fish_path.u8_lut)
+    free (babl->fish_path.u8_lut);
+  babl->fish_path.u8_lut = NULL;
   if (babl->fish_path.conversion_list)
     babl_free (babl->fish_path.conversion_list);
   babl->fish_path.conversion_list = NULL;
@@ -663,6 +666,10 @@ babl_fish_path2 (const Babl *source,
       )
      )
   {
+     // as long as the highest 8bit of the 32bit of a 4 byte input is ignored
+     // (alpha) - and it is not an associated color model. A 24 bit LUT provides
+     // exact data. Thus this is valid for instance for "YA half"
+
      if ((source->format.model->flags & BABL_MODEL_FLAG_ASSOCIATED)==0)
        babl->fish_path.is_u8_color_conv = 1;
   }
@@ -711,6 +718,44 @@ babl_fish_path (const Babl *source,
   return babl_fish_path2 (source, destination, 0.0);
 }
 
+typedef struct GcContext {
+   long time;
+} GcContext;
+
+static int gc_fishes (Babl *babl, void *userdata)
+{
+  GcContext *context = userdata;
+  if (babl->class_type == BABL_FISH_PATH)
+  {
+    if (babl->fish_path.u8_lut)
+    {
+      if (context->time - babl->fish_path.last_lut_use >
+          1000 * 1000 * 60 * )
+      {
+        void *lut =babl->fish_path.u8_lut;
+        BABL(babl)->fish_path.u8_lut = NULL;
+        free (lut);
+#if 0
+        fprintf (stderr, "freeing LUT %s to %s unused for >5 minutes\n",
+                        babl_get_name (babl->conversion.source),
+                        babl_get_name (babl->conversion.destination));
+#endif
+      }
+    }
+  }
+  return 0;
+}
+                           
+static void
+babl_gc_fishes (void)
+{
+  GcContext context;
+  context.time = babl_ticks ();
+  babl_fish_class_for_each (gc_fishes, &context);
+  //malloc_trim (0); 
+  //  is responsibility of higher layers
+}
+
 static void
 babl_fish_path_process (const Babl *babl,
                         const char *source,
@@ -821,9 +866,20 @@ babl_fish_path_process (const Babl *babl,
              *dst++ = lut[col & 0xffffff] | (col & 0xff000000);
           }
         }
+        BABL(babl)->fish_path.last_lut_use = babl_ticks ();
         return;
      }
   }
+  else
+  {
+    static long conv_counter = 0;
+    conv_counter+=n;
+    if (conv_counter > 1000 * 1000 * 10) // possibly run gc every 10 megapixels
+    {
+      babl_gc_fishes ();
+      conv_counter = 0;
+    }
+  }
   process_conversion_path (babl->fish_path.conversion_list,
                            source,
                            babl->fish_path.source_bpp,
diff --git a/babl/babl-fish.h b/babl/babl-fish.h
index 966fa4e..dfe07a3 100644
--- a/babl/babl-fish.h
+++ b/babl/babl-fish.h
@@ -71,6 +71,7 @@ typedef struct
   int        dest_bpp;
   unsigned int is_u8_color_conv:1; // keep track of count, and make 
   uint8_t   *u8_lut;
+  long       last_lut_use;
   BablList  *conversion_list;
 } BablFishPath;
 
diff --git a/babl/base/model-gray.c b/babl/base/model-gray.c
index 9a74096..7441baa 100644
--- a/babl/base/model-gray.c
+++ b/babl/base/model-gray.c
@@ -90,7 +90,6 @@ models (void)
     "linear",
     NULL);
 
-
   babl_model_new (
     "id", BABL_GRAY_ALPHA,
     babl_component_from_id (BABL_GRAY_LINEAR),


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