[pango/speed-up-format-filtering: 5/8] Call FcInit in a thread




commit d858e82bf3da0c4fc412f9451071f7f71c670dde
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Aug 19 14:09:00 2020 -0400

    Call FcInit in a thread
    
    With a big fontconfig configuration, FcInit takes some
    time (60-100ms on my system). Doing this work off the
    main thread can potentially avoid blocking other work.
    
    Unfortunately, it currently doesn't, since we have to
    wait for the result shortly after kicking off the thread.
    This could be improved by moving things ot a constructor,
    or some explicit init call.

 pango/pangofc-fontmap.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)
---
diff --git a/pango/pangofc-fontmap.c b/pango/pangofc-fontmap.c
index fd1256a3..e5cdaccf 100644
--- a/pango/pangofc-fontmap.c
+++ b/pango/pangofc-fontmap.c
@@ -109,6 +109,14 @@
  *   FcCharSetMerge().
  */
 
+/* We call FcInit in a thread and set fc_initialized
+ * when done, and are protected by a mutex. The thread
+ * signals the cond when FcInit is done.
+ */
+static GMutex fc_init_mutex;
+static GCond fc_init_cond;
+static gboolean fc_initialized;
+
 
 typedef struct _PangoFcFontFaceData PangoFcFontFaceData;
 typedef struct _PangoFcFace         PangoFcFace;
@@ -1313,6 +1321,29 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (PangoFcFontMap, pango_fc_font_map, PANGO_TYPE_
                                   G_ADD_PRIVATE (PangoFcFontMap)
                                   G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, 
pango_fc_font_map_list_model_init))
 
+static void
+init_in_thread (GTask        *task,
+                gpointer      source_object,
+                gpointer      task_data,
+                GCancellable *cancellable)
+{
+  FcInit ();
+
+  g_mutex_lock (&fc_init_mutex);
+  fc_initialized = TRUE;
+  g_cond_signal (&fc_init_cond);
+  g_mutex_unlock (&fc_init_mutex);
+}
+
+static void
+wait_for_fc_init (void)
+{
+  g_mutex_lock (&fc_init_mutex);
+  while (!fc_initialized)
+    g_cond_wait (&fc_init_cond, &fc_init_mutex);
+  g_mutex_unlock (&fc_init_mutex);
+}
+
 static void
 pango_fc_font_map_init (PangoFcFontMap *fcfontmap)
 {
@@ -1343,6 +1374,16 @@ pango_fc_font_map_init (PangoFcFontMap *fcfontmap)
                                                     (GDestroyNotify)pango_fc_font_face_data_free,
                                                     NULL);
   priv->dpi = -1;
+
+  if (!fc_initialized)
+    {
+      GTask *task;
+
+      task = g_task_new (fcfontmap, NULL, NULL, NULL);
+      g_task_set_name (task, "[pango] FcInit");
+      g_task_run_in_thread (task, init_in_thread);
+      g_object_unref (task);
+    }
 }
 
 static void
@@ -1568,6 +1609,8 @@ ensure_families (PangoFcFontMap *fcfontmap)
   int i;
   int count;
 
+  wait_for_fc_init ();
+
   if (priv->n_families < 0)
     {
       FcObjectSet *os = FcObjectSetBuild (FC_FAMILY, FC_SPACING, FC_STYLE, FC_WEIGHT, FC_WIDTH, FC_SLANT,
@@ -2220,6 +2263,9 @@ pango_fc_font_map_set_config (PangoFcFontMap *fcfontmap,
 
   if (oldconfig)
     FcConfigDestroy (oldconfig);
+
+  /* No need to wait anymore */
+  fc_initialized = TRUE;
 }
 
 /**
@@ -2240,6 +2286,8 @@ pango_fc_font_map_get_config (PangoFcFontMap *fcfontmap)
 {
   g_return_val_if_fail (PANGO_IS_FC_FONT_MAP (fcfontmap), NULL);
 
+  wait_for_fc_init ();
+
   return fcfontmap->priv->config;
 }
 
@@ -2251,6 +2299,8 @@ pango_fc_font_map_get_config_fonts (PangoFcFontMap *fcfontmap,
   int set;
   int n;
 
+  wait_for_fc_init ();
+
   n = 0;
   for (set = 0; set < 2; set++)
     {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]