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




commit 1ba764f329faf4e0d392d4ce1e9b809c04b6469d
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.
    
    To take advantage of this, GTK calls pango_cairo_font_map_get_default()
    early to initiate the creation of a fontmap, thereby triggering the
    FcInit() call.

 pango/pangofc-fontmap.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)
---
diff --git a/pango/pangofc-fontmap.c b/pango/pangofc-fontmap.c
index dbb6d5a4..f6655986 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;
@@ -1318,6 +1326,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)
 {
@@ -1348,6 +1379,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
@@ -1570,6 +1611,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,
@@ -2219,6 +2262,9 @@ pango_fc_font_map_set_config (PangoFcFontMap *fcfontmap,
 
   if (oldconfig)
     FcConfigDestroy (oldconfig);
+
+  /* No need to wait anymore */
+  fc_initialized = TRUE;
 }
 
 /**
@@ -2239,6 +2285,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;
 
+      wait_for_fc_init ();
+
       for (set = 0; set < 2; set++)
         {
           FcFontSet *fonts;


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