diff options
author | Matthias Clasen <mclasen@redhat.com> | 2020-08-19 14:09:00 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2021-02-22 08:27:16 -0500 |
commit | e4e7a76a173620394a4bff9738d9b156c40e8c45 (patch) | |
tree | 256d1aea4760c4e331a3554bd24baf5454a0853a /pango/pangofc-fontmap.c | |
parent | 8f15d1b320f1d859cc0a1a70c1de3c8092ba6b43 (diff) | |
download | pango-e4e7a76a173620394a4bff9738d9b156c40e8c45.tar.gz |
Move FcInit call to 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.
Diffstat (limited to 'pango/pangofc-fontmap.c')
-rw-r--r-- | pango/pangofc-fontmap.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/pango/pangofc-fontmap.c b/pango/pangofc-fontmap.c index 14492607..9364c082 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; @@ -1314,6 +1322,29 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (PangoFcFontMap, pango_fc_font_map, PANGO_TYPE_ 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) { PangoFcFontMapPrivate *priv; @@ -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 @@ -1567,6 +1608,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, @@ -2233,6 +2276,9 @@ pango_fc_font_map_set_config (PangoFcFontMap *fcfontmap, if (oldconfig) FcConfigDestroy (oldconfig); + + /* No need to wait anymore */ + fc_initialized = TRUE; } /** @@ -2253,6 +2299,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; } @@ -2263,6 +2311,8 @@ pango_fc_font_map_get_config_fonts (PangoFcFontMap *fcfontmap) { FcFontSet *sets[2]; + wait_for_fc_init (); + sets[0] = FcConfigGetFonts (fcfontmap->priv->config, 0); sets[1] = FcConfigGetFonts (fcfontmap->priv->config, 1); fcfontmap->priv->fonts = filter_by_format (sets, 2); |