[gtk/matthiasc/color-profile-rebased: 19/46] colorprofile: Implement a global transform cache




commit 6d8f12ae48ac2c2936f10657c86a03481319a0b4
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        | 80 ++++++++++++++++++++++++++++++++++++++++++++
 gdk/gdkcolorprofileprivate.h |  5 +++
 gdk/gdkmemoryformat.c        | 12 +++----
 3 files changed, 90 insertions(+), 7 deletions(-)
---
diff --git a/gdk/gdkcolorprofile.c b/gdk/gdkcolorprofile.c
index abf36132b9..45667870af 100644
--- a/gdk/gdkcolorprofile.c
+++ b/gdk/gdkcolorprofile.c
@@ -406,3 +406,83 @@ gdk_color_profile_supports_memory_format (GdkColorProfile *profile,
    */
   return cmsGetColorSpace (profile->lcms_profile) == cmsSigRgbData;
 }
+
+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 8aef0561fb..ab87ccde82 100644
--- a/gdk/gdkcolorprofileprivate.h
+++ b/gdk/gdkcolorprofileprivate.h
@@ -18,6 +18,11 @@ cmsHPROFILE *                gdk_color_profile_get_lcms_profile           (GdkCo
 gboolean                     gdk_color_profile_supports_memory_format     (GdkColorProfile      *profile,
                                                                            GdkMemoryFormat       format);
 
+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 cbaddfacab..d7f080b842 100644
--- a/gdk/gdkmemoryformat.c
+++ b/gdk/gdkmemoryformat.c
@@ -847,12 +847,11 @@ gdk_memory_convert_transform (guchar              *dest_data,
   guchar *src_tmp, *dest_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)
     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]