[gtk/wip/otte/color-profiles: 4/8] colorprofile: Implement a global transform cache
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/color-profiles: 4/8] colorprofile: Implement a global transform cache
- Date: Mon, 27 Sep 2021 04:05:44 +0000 (UTC)
commit a3e77e060af7d5901e6b9d2f7875e71c54ed9014
Author: Benjamin Otte <otte redhat com>
Date: Mon Sep 27 00:45:26 2021 +0200
colorprofile: Implement a global transform cache
Speeds up things by a factor of 10x, so seems like a good idea.
The cache is never purges, we might want to fix that.
gdk/gdkcolorprofile.c | 79 ++++++++++++++++++++++++++++++++++++++++++++
gdk/gdkcolorprofileprivate.h | 5 +++
gdk/gdkmemoryformat.c | 13 +++-----
3 files changed, 89 insertions(+), 8 deletions(-)
---
diff --git a/gdk/gdkcolorprofile.c b/gdk/gdkcolorprofile.c
index 6722b44b6f..6d7a98b3c0 100644
--- a/gdk/gdkcolorprofile.c
+++ b/gdk/gdkcolorprofile.c
@@ -391,3 +391,82 @@ gdk_color_profile_equal (gconstpointer profile1,
GDK_COLOR_PROFILE (profile2)->icc_profile);
}
+typedef struct _GdkColorTransformCache GdkColorTransformCache;
+
+struct _GdkColorTransformCache
+{
+ GdkColorProfile *source;
+ guint source_type;
+ GdkColorProfile *dest;
+ guint dest_type;
+};
+
+static void
+gdk_color_transform_cache_free (gpointer data)
+{
+ g_free (data);
+}
+
+static guint
+gdk_color_transform_cache_hash (gconstpointer data)
+{
+ const GdkColorTransformCache *cache = data;
+
+ return g_direct_hash (cache->source) ^
+ (g_direct_hash (cache->dest) >> 2) ^
+ ((cache->source_type << 16) | (cache->source_type >> 16)) ^
+ cache->dest_type;
+}
+
+static gboolean
+gdk_color_transform_cache_equal (gconstpointer data1,
+ gconstpointer data2)
+{
+ const GdkColorTransformCache *cache1 = data1;
+ const GdkColorTransformCache *cache2 = data2;
+
+ return cache1->source == cache2->source &&
+ cache1->source_type == cache2->source_type &&
+ cache1->dest == cache2->dest &&
+ cache1->dest_type == cache2->dest_type;
+}
+
+cmsHTRANSFORM *
+gdk_color_profile_lookup_transform (GdkColorProfile *source,
+ guint source_type,
+ GdkColorProfile *dest,
+ guint dest_type)
+{
+ GdkColorTransformCache *entry;
+ static GHashTable *cache = NULL;
+ cmsHTRANSFORM *transform;
+
+ if (cache == NULL)
+ cache = g_hash_table_new_full (gdk_color_transform_cache_hash,
+ gdk_color_transform_cache_equal,
+ gdk_color_transform_cache_free,
+ cmsDeleteTransform);
+
+ transform = g_hash_table_lookup (cache,
+ &(GdkColorTransformCache) {
+ source, source_type,
+ dest, dest_type
+ });
+ if (G_UNLIKELY (transform == NULL))
+ {
+ transform = cmsCreateTransform (gdk_color_profile_get_lcms_profile (source),
+ source_type,
+ gdk_color_profile_get_lcms_profile (dest),
+ dest_type,
+ INTENT_PERCEPTUAL,
+ cmsFLAGS_COPY_ALPHA);
+ entry = g_new (GdkColorTransformCache, 1);
+ *entry = (GdkColorTransformCache) {
+ source, source_type,
+ dest, dest_type
+ };
+ g_hash_table_insert (cache, entry, transform);
+ }
+
+ return transform;
+}
diff --git a/gdk/gdkcolorprofileprivate.h b/gdk/gdkcolorprofileprivate.h
index 16a02196ed..41dd99c457 100644
--- a/gdk/gdkcolorprofileprivate.h
+++ b/gdk/gdkcolorprofileprivate.h
@@ -14,6 +14,11 @@ GdkColorProfile * gdk_color_profile_new_from_lcms_profile (cmsHP
cmsHPROFILE * gdk_color_profile_get_lcms_profile (GdkColorProfile *self);
+cmsHTRANSFORM * gdk_color_profile_lookup_transform (GdkColorProfile *source,
+ guint source_type,
+ GdkColorProfile *dest,
+ guint dest_type);
+
G_END_DECLS
#endif /* __GDK_COLOR_PROFILE_PRIVATE_H__ */
diff --git a/gdk/gdkmemoryformat.c b/gdk/gdkmemoryformat.c
index 2861606adf..3fd7038936 100644
--- a/gdk/gdkmemoryformat.c
+++ b/gdk/gdkmemoryformat.c
@@ -808,12 +808,11 @@ gdk_memory_convert_transform (guchar *dest_data,
guchar *tmp;
gsize y;
- transform = cmsCreateTransform (gdk_color_profile_get_lcms_profile (src_profile),
- src_desc->lcms.type,
- gdk_color_profile_get_lcms_profile (dest_profile),
- dest_desc->lcms.type,
- INTENT_PERCEPTUAL,
- cmsFLAGS_COPY_ALPHA);
+ transform = gdk_color_profile_lookup_transform (src_profile,
+ src_desc->lcms.type,
+ dest_profile,
+ dest_desc->lcms.type);
+
if (src_desc->to_lcms)
tmp = g_malloc_n (src_desc->lcms.bpp, width);
else
@@ -835,8 +834,6 @@ gdk_memory_convert_transform (guchar *dest_data,
src_data += src_stride;
dest_data += dest_stride;
}
-
- cmsDeleteTransform (transform);
}
void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]