[gimp] libgimpwidgets: cache gimp_widget_get_color_transform()'s GimpColorTransforms
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] libgimpwidgets: cache gimp_widget_get_color_transform()'s GimpColorTransforms
- Date: Fri, 27 May 2016 19:59:47 +0000 (UTC)
commit d6ee1dc5cf5c2a8751a76abaf307910318abe527
Author: Michael Natterer <mitch gimp org>
Date: Fri May 27 21:55:06 2016 +0200
libgimpwidgets: cache gimp_widget_get_color_transform()'s GimpColorTransforms
Now that more and more widgets are color managed, we need transforms
for all of them. Creating them is very expensive.
The new cache returns the same transform for a combination of (config,
src_profile, src_format, dest_format) and invalidates itself
automatically on config changes. The number of transforms goes down
from potentially hundreds to a handful, and the cost of a config
change from many seconds to virtually instant.
libgimpwidgets/gimpwidgetsutils.c | 181 +++++++++++++++++++++++++++++++++----
1 files changed, 161 insertions(+), 20 deletions(-)
---
diff --git a/libgimpwidgets/gimpwidgetsutils.c b/libgimpwidgets/gimpwidgetsutils.c
index 659e7bd..0f5e4e4 100644
--- a/libgimpwidgets/gimpwidgetsutils.c
+++ b/libgimpwidgets/gimpwidgetsutils.c
@@ -479,6 +479,87 @@ get_display_profile (GtkWidget *widget,
return profile;
}
+typedef struct _TransformCache TransformCache;
+
+struct _TransformCache
+{
+ GimpColorTransform *transform;
+
+ GimpColorConfig *config;
+ GimpColorProfile *src_profile;
+ const Babl *src_format;
+ GimpColorProfile *dest_profile;
+ const Babl *dest_format;
+ GimpColorProfile *proof_profile;
+
+ gulong notify_id;
+};
+
+static GList *transform_caches = NULL;
+static gboolean debug_cache = FALSE;
+
+static gboolean
+profiles_equal (GimpColorProfile *profile1,
+ GimpColorProfile *profile2)
+{
+ return ((profile1 == NULL && profile2 == NULL) ||
+ (profile1 != NULL && profile2 != NULL &&
+ gimp_color_profile_is_equal (profile1, profile2)));
+}
+
+static TransformCache *
+transform_cache_get (GimpColorConfig *config,
+ GimpColorProfile *src_profile,
+ const Babl *src_format,
+ GimpColorProfile *dest_profile,
+ const Babl *dest_format,
+ GimpColorProfile *proof_profile)
+{
+ GList *list;
+
+ for (list = transform_caches; list; list = g_list_next (list))
+ {
+ TransformCache *cache = list->data;
+
+ if (config == cache->config &&
+ src_format == cache->src_format &&
+ dest_format == cache->dest_format &&
+ profiles_equal (src_profile, cache->src_profile) &&
+ profiles_equal (dest_profile, cache->dest_profile) &&
+ profiles_equal (proof_profile, cache->proof_profile))
+ {
+ if (debug_cache)
+ g_printerr ("found cache %p\n", cache);
+
+ return cache;
+ }
+ }
+
+ return NULL;
+}
+
+static void
+transform_cache_config_notify (GObject *config,
+ const GParamSpec *pspec,
+ TransformCache *cache)
+{
+ transform_caches = g_list_remove (transform_caches, cache);
+
+ g_signal_handler_disconnect (config, cache->notify_id);
+
+ g_object_unref (cache->transform);
+ g_object_unref (cache->src_profile);
+ g_object_unref (cache->dest_profile);
+
+ if (cache->proof_profile)
+ g_object_unref (cache->proof_profile);
+
+ g_free (cache);
+
+ if (debug_cache)
+ g_printerr ("deleted cache %p\n", cache);
+}
+
GimpColorTransform *
gimp_widget_get_color_transform (GtkWidget *widget,
GimpColorConfig *config,
@@ -486,17 +567,24 @@ gimp_widget_get_color_transform (GtkWidget *widget,
const Babl *src_format,
const Babl *dest_format)
{
- GimpColorTransform *transform = NULL;
+ static gboolean initialized = FALSE;
GimpColorProfile *dest_profile = NULL;
GimpColorProfile *proof_profile = NULL;
- cmsUInt16Number alarmCodes[cmsMAXCHANNELS] = { 0, };
+ TransformCache *cache;
g_return_val_if_fail (widget == NULL || GTK_IS_WIDGET (widget), NULL);
- g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (src_profile), NULL);
g_return_val_if_fail (GIMP_IS_COLOR_CONFIG (config), NULL);
+ g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (src_profile), NULL);
g_return_val_if_fail (src_format != NULL, NULL);
g_return_val_if_fail (dest_format != NULL, NULL);
+ if (G_UNLIKELY (! initialized))
+ {
+ initialized = TRUE;
+
+ debug_cache = g_getenv ("GIMP_DEBUG_TRANSFORM_CACHE") != NULL;
+ }
+
switch (config->mode)
{
case GIMP_COLOR_MANAGEMENT_OFF:
@@ -511,7 +599,54 @@ gimp_widget_get_color_transform (GtkWidget *widget,
break;
}
- if (proof_profile)
+ cache = transform_cache_get (config,
+ src_profile,
+ src_format,
+ dest_profile,
+ dest_format,
+ proof_profile);
+
+ if (cache)
+ {
+ g_object_unref (dest_profile);
+
+ if (proof_profile)
+ g_object_unref (proof_profile);
+
+ if (cache->transform)
+ return g_object_ref (cache->transform);
+
+ return NULL;
+ }
+
+ if (! proof_profile &&
+ gimp_color_profile_is_equal (src_profile, dest_profile))
+ {
+ g_object_unref (dest_profile);
+
+ return NULL;
+ }
+
+ cache = g_new0 (TransformCache, 1);
+
+ if (debug_cache)
+ g_printerr ("creating cache %p\n", cache);
+
+ cache->config = g_object_ref (config);
+ cache->src_profile = g_object_ref (src_profile);
+ cache->src_format = src_format;
+ cache->dest_profile = dest_profile;
+ cache->dest_format = dest_format;
+ cache->proof_profile = proof_profile;
+
+ cache->notify_id =
+ g_signal_connect (cache->config, "notify",
+ G_CALLBACK (transform_cache_config_notify),
+ cache);
+
+ transform_caches = g_list_prepend (transform_caches, cache);
+
+ if (cache->proof_profile)
{
GimpColorTransformFlags flags = 0;
@@ -522,7 +657,8 @@ gimp_widget_get_color_transform (GtkWidget *widget,
if (config->simulation_gamut_check)
{
- guchar r, g, b;
+ cmsUInt16Number alarmCodes[cmsMAXCHANNELS] = { 0, };
+ guchar r, g, b;
flags |= GIMP_COLOR_TRANSFORM_FLAGS_GAMUT_CHECK;
@@ -535,16 +671,17 @@ gimp_widget_get_color_transform (GtkWidget *widget,
cmsSetAlarmCodes (alarmCodes);
}
- transform = gimp_color_transform_new_proofing (src_profile, src_format,
- dest_profile, dest_format,
- proof_profile,
- config->simulation_intent,
- config->display_intent,
- flags);
-
- g_object_unref (proof_profile);
+ cache->transform =
+ gimp_color_transform_new_proofing (cache->src_profile,
+ cache->src_format,
+ cache->dest_profile,
+ cache->dest_format,
+ cache->proof_profile,
+ config->simulation_intent,
+ config->display_intent,
+ flags);
}
- else if (! gimp_color_profile_is_equal (src_profile, dest_profile))
+ else
{
GimpColorTransformFlags flags = 0;
@@ -553,13 +690,17 @@ gimp_widget_get_color_transform (GtkWidget *widget,
flags |= GIMP_COLOR_TRANSFORM_FLAGS_BLACK_POINT_COMPENSATION;
}
- transform = gimp_color_transform_new (src_profile, src_format,
- dest_profile, dest_format,
- config->display_intent,
- flags);
+ cache->transform =
+ gimp_color_transform_new (cache->src_profile,
+ cache->src_format,
+ cache->dest_profile,
+ cache->dest_format,
+ config->display_intent,
+ flags);
}
- g_object_unref (dest_profile);
+ if (cache->transform)
+ return g_object_ref (cache->transform);
- return transform;
+ return NULL;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]