[gtk/matthiasc/color-profile-rebased: 40/66] lcmscolorspace: Implement a global transform cache




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]