[gtk/matthiasc/color-profile-rebased: 40/66] lcmscolorspace: Implement a global transform cache
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/matthiasc/color-profile-rebased: 40/66] lcmscolorspace: Implement a global transform cache
- Date: Fri, 13 May 2022 04:00:02 +0000 (UTC)
commit 0f9a9af2be49e1c84e61e1d6daddc8aac8fd9ed1
Author: Matthias Clasen <mclasen redhat com>
Date: Thu May 12 19:55:07 2022 -0400
lcmscolorspace: 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/gdklcmscolorspace.c | 80 ++++++++++++++++++++++++++++++++++++++++++
gdk/gdklcmscolorspaceprivate.h | 5 +++
gdk/gdkmemoryformat.c | 19 +++++-----
3 files changed, 95 insertions(+), 9 deletions(-)
---
diff --git a/gdk/gdklcmscolorspace.c b/gdk/gdklcmscolorspace.c
index fa917dea7a..176358c78a 100644
--- a/gdk/gdklcmscolorspace.c
+++ b/gdk/gdklcmscolorspace.c
@@ -234,3 +234,83 @@ gdk_color_space_get_srgb_linear (void)
return srgb_linear_color_space;
}
+
+typedef struct _GdkColorTransformCache GdkColorTransformCache;
+
+struct _GdkColorTransformCache
+{
+ GdkColorSpace *source;
+ guint source_type;
+ GdkColorSpace *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_lcms_color_space_lookup_transform (GdkColorSpace *source,
+ guint source_type,
+ GdkColorSpace *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_lcms_color_space_get_lcms_profile (source),
+ source_type,
+ gdk_lcms_color_space_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/gdklcmscolorspaceprivate.h b/gdk/gdklcmscolorspaceprivate.h
index 2251c394d2..96f025cbb1 100644
--- a/gdk/gdklcmscolorspaceprivate.h
+++ b/gdk/gdklcmscolorspaceprivate.h
@@ -43,6 +43,11 @@ GType gdk_lcms_color_space_get_type (void) G
GdkColorSpace * gdk_lcms_color_space_new_from_lcms_profile (cmsHPROFILE
lcms_profile);
cmsHPROFILE gdk_lcms_color_space_get_lcms_profile (GdkColorSpace
*color_space);
+cmsHTRANSFORM * gdk_lcms_color_space_lookup_transform (GdkColorSpace *source,
+ guint source_type,
+ GdkColorSpace *dest,
+ guint dest_type);
+
G_END_DECLS
#endif /* __GDK_LCMS_COLOR_SPACE_PRIVATE_H__ */
diff --git a/gdk/gdkmemoryformat.c b/gdk/gdkmemoryformat.c
index 32e93c05aa..2688f9c904 100644
--- a/gdk/gdkmemoryformat.c
+++ b/gdk/gdkmemoryformat.c
@@ -833,11 +833,11 @@ static void
gdk_memory_convert_transform (guchar *dest_data,
gsize dest_stride,
GdkMemoryFormat dest_format,
- GdkColorSpace *dest_space,
+ GdkColorSpace *dest_color_space,
const guchar *src_data,
gsize src_stride,
GdkMemoryFormat src_format,
- GdkColorSpace *src_space,
+ GdkColorSpace *src_color_space,
gsize width,
gsize height)
{
@@ -847,12 +847,14 @@ gdk_memory_convert_transform (guchar *dest_data,
guchar *src_tmp, *dest_tmp;
gsize y;
- transform = cmsCreateTransform (gdk_lcms_color_space_get_lcms_profile (src_space),
- src_desc->lcms.type,
- gdk_lcms_color_space_get_lcms_profile (dest_space),
- dest_desc->lcms.type,
- INTENT_PERCEPTUAL,
- cmsFLAGS_COPY_ALPHA);
+ g_assert (GDK_IS_LCMS_COLOR_SPACE (dest_color_space));
+ g_assert (GDK_IS_LCMS_COLOR_SPACE (src_color_space));
+
+ transform = gdk_lcms_color_space_lookup_transform (src_color_space,
+ src_desc->lcms.type,
+ dest_color_space,
+ dest_desc->lcms.type);
+
if (src_desc->to_lcms)
src_tmp = g_malloc_n (src_desc->lcms.bpp, width);
else
@@ -881,7 +883,6 @@ gdk_memory_convert_transform (guchar *dest_data,
g_free (src_tmp);
g_free (dest_tmp);
- cmsDeleteTransform (transform);
}
void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]