Bug 449848 - Startup: initialize fontconfig in the background ...

... to avoid long pause on start

On non-Linux operating systems the fontconfig cache is often not
initialized by default. The first time GIMP was launched, this led
to a non-responding application, confusing many users.

The initialization of fontconfig has now been moved to a separate
thread. The main thread will wait for this fontconfig thread to
complete, regularly pulsing the UI.

This patch was partly based on an earlier patch by Tor Lillqvist.
This commit is contained in:
Kristian Rietveld 2016-04-17 17:27:06 +01:00
parent d23135ef97
commit 30b73125f8
3 changed files with 75 additions and 7 deletions

View File

@ -1119,7 +1119,7 @@ gimp_restore (Gimp *gimp,
/* initialize the list of fonts */
status_callback (NULL, _("Fonts (this may take a while)"), 0.6);
if (! gimp->no_fonts)
gimp_fonts_load (gimp);
gimp_fonts_load_with_status (gimp, status_callback);
/* initialize the color history */
gimp_palettes_load (gimp);

View File

@ -58,8 +58,39 @@ gimp_fonts_init (Gimp *gimp)
G_CALLBACK (gimp_fonts_load), gimp);
}
typedef struct
{
FcConfig *config;
GMutex mutex;
GCond cond;
gboolean caching_complete : 1;
} GimpFontsLoadFuncData;
static void
gimp_fonts_load_func (FcConfig *config)
{
if (! FcConfigBuildFonts (config))
FcConfigDestroy (config);
else
FcConfigSetCurrent (config);
}
static void
gimp_fonts_load_thread (GimpFontsLoadFuncData *data)
{
gimp_fonts_load_func (data->config);
g_mutex_lock (&data->mutex);
data->caching_complete = TRUE;
g_cond_signal (&data->cond);
g_mutex_unlock (&data->mutex);
g_thread_exit (0);
}
void
gimp_fonts_load (Gimp *gimp)
gimp_fonts_load_with_status (Gimp *gimp,
GimpInitStatusFunc status_callback)
{
FcConfig *config;
GFile *fonts_conf;
@ -93,13 +124,42 @@ gimp_fonts_load (Gimp *gimp)
gimp_fonts_add_directories (config, path);
g_list_free_full (path, (GDestroyNotify) g_object_unref);
if (! FcConfigBuildFonts (config))
if (status_callback)
{
FcConfigDestroy (config);
goto cleanup;
}
gint64 end_time;
GThread *cache_thread;
GimpFontsLoadFuncData data;
FcConfigSetCurrent (config);
/* We perform font cache initialization in a separate thread, so
* in the case a cache rebuild is to be done it will not block
* the UI.
*/
data.config = config;
g_mutex_init (&data.mutex);
g_cond_init (&data.cond);
data.caching_complete = FALSE;
cache_thread = g_thread_new ("font-cacher",
(GThreadFunc) gimp_fonts_load_thread,
&data);
g_mutex_lock (&data.mutex);
end_time = g_get_monotonic_time () + 0.1 * G_TIME_SPAN_SECOND;
while (!data.caching_complete)
if (!g_cond_wait_until (&data.cond, &data.mutex, end_time))
{
status_callback (NULL, NULL, 0.6);
end_time += 0.1 * G_TIME_SPAN_SECOND;
continue;
}
g_mutex_unlock (&data.mutex);
g_thread_join (cache_thread);
}
else
gimp_fonts_load_func (config);
gimp_font_list_restore (GIMP_FONT_LIST (gimp->fonts));
@ -108,6 +168,12 @@ gimp_fonts_load (Gimp *gimp)
gimp_unset_busy (gimp);
}
void
gimp_fonts_load (Gimp *gimp)
{
gimp_fonts_load_with_status (gimp, NULL);
}
void
gimp_fonts_reset (Gimp *gimp)
{

View File

@ -21,6 +21,8 @@
void gimp_fonts_init (Gimp *gimp);
void gimp_fonts_load (Gimp *gimp);
void gimp_fonts_load_with_status (Gimp *gimp,
GimpInitStatusFunc status_callback);
void gimp_fonts_reset (Gimp *gimp);