[gtk/matthiasc/color-profile-rebased: 23/51] 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: 23/51] lcmscolorspace: Implement a global transform cache
- Date: Sat, 1 Oct 2022 01:36:42 +0000 (UTC)
commit 4137f26f413cb2a0d2532ca44ced046d562d7389
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/gdkcolorspaceprivate.h | 6 ++++
gdk/gdklcmscolorspace.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++
gdk/gdkmemoryformat.c | 16 ++++------
3 files changed, 93 insertions(+), 9 deletions(-)
---
diff --git a/gdk/gdkcolorspaceprivate.h b/gdk/gdkcolorspaceprivate.h
index b85bbc65fa..3b616c3edf 100644
--- a/gdk/gdkcolorspaceprivate.h
+++ b/gdk/gdkcolorspaceprivate.h
@@ -2,6 +2,7 @@
#define __GDK_COLOR_SPACE_PRIVATE_H__
#include "gdkcolorspace.h"
+#include <lcms2.h>
G_BEGIN_DECLS
@@ -28,6 +29,11 @@ struct _GdkColorSpaceClass
GdkColorSpace * gdk_color_space_get_srgb_linear (void) G_GNUC_CONST;
+cmsHTRANSFORM * gdk_color_space_lookup_transform (GdkColorSpace *source,
+ guint source_type,
+ GdkColorSpace *dest,
+ guint dest_type);
+
G_END_DECLS
#endif /* __GDK_COLOR_SPACE_PRIVATE_H__ */
diff --git a/gdk/gdklcmscolorspace.c b/gdk/gdklcmscolorspace.c
index 80e3721819..cb6d80019f 100644
--- a/gdk/gdklcmscolorspace.c
+++ b/gdk/gdklcmscolorspace.c
@@ -253,3 +253,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_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 && source && dest))
+ {
+ 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/gdkmemoryformat.c b/gdk/gdkmemoryformat.c
index 32e93c05aa..6c0a1bcf44 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,11 @@ 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);
+ transform = gdk_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 +880,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]