[gtk/wip/otte/color-profiles: 2/4] colorprofile: Implement a global transform cache




commit 0c7799a42212c5d0a4667f171149b01121b4bbca
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]