From a281849c29c407c69dc1f6cc8513c9e5b92a428b Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C3=98yvind=20Kol=C3=A5s?= Date: Mon, 24 Jan 2022 03:56:09 +0100 Subject: [PATCH] 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), -- 2.30.2