From 1b0cc40826c56d53d1ec9430e0125f00f266bc96 Mon Sep 17 00:00:00 2001 From: raveit65 Date: Sun, 8 Jan 2017 19:28:48 +0100 Subject: Fontviewer: model: use a single IO scheduler job to load thumbnail images Instead of firing a new thread for all files. Using g_io_scheduler_job_send_to_mainloop_async() we can load thumbnails into the model as they get created anyway. taken from: https://git.gnome.org/browse/gnome-font-viewer/commit/?id=4f08812 --- font-viewer/font-model.c | 128 +++++++++++++++++++++++------------------------ 1 file changed, 64 insertions(+), 64 deletions(-) diff --git a/font-viewer/font-model.c b/font-viewer/font-model.c index c89c0144..9d0da653 100644 --- a/font-viewer/font-model.c +++ b/font-viewer/font-model.c @@ -149,7 +149,7 @@ load_thumbnail_data_free (LoadThumbnailData *data) } static gboolean -ensure_thumbnail_job_done (gpointer user_data) +one_thumbnail_done (gpointer user_data) { LoadThumbnailData *data = user_data; @@ -208,83 +208,72 @@ create_thumbnail (LoadThumbnailData *data) } static gboolean -ensure_thumbnail_job (GIOSchedulerJob *job, - GCancellable *cancellable, - gpointer user_data) +ensure_thumbnails_job (GIOSchedulerJob *job, + GCancellable *cancellable, + gpointer user_data) { - LoadThumbnailData *data = user_data; - gboolean thumb_failed; - const gchar *thumb_path; - - GError *error = NULL; - GFile *thumb_file = NULL; - GFileInputStream *is = NULL; - GFileInfo *info = NULL; - - info = g_file_query_info (data->font_file, - ATTRIBUTES_FOR_EXISTING_THUMBNAIL, - G_FILE_QUERY_INFO_NONE, - NULL, &error); - - if (error != NULL) { - g_debug ("Can't query info for file %s: %s\n", data->font_path, error->message); - goto out; - } + GList *thumbnails = user_data, *l; - thumb_failed = g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED); - if (thumb_failed) - goto out; + for (l = thumbnails; l != NULL; l = l->next) { + gboolean thumb_failed; + const gchar *thumb_path; + LoadThumbnailData *data = l->data; - thumb_path = g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH); + GError *error = NULL; + GFile *thumb_file = NULL; + GFileInputStream *is = NULL; + GFileInfo *info = NULL; - if (thumb_path != NULL) { - thumb_file = g_file_new_for_path (thumb_path); - is = g_file_read (thumb_file, NULL, &error); + info = g_file_query_info (data->font_file, + ATTRIBUTES_FOR_EXISTING_THUMBNAIL, + G_FILE_QUERY_INFO_NONE, + NULL, &error); if (error != NULL) { - g_debug ("Can't read file %s: %s\n", thumb_path, error->message); - goto out; + g_debug ("Can't query info for file %s: %s\n", data->font_path, error->message); + goto next; } - data->pixbuf = gdk_pixbuf_new_from_stream_at_scale (G_INPUT_STREAM (is), - 128, 128, TRUE, - NULL, &error); + thumb_failed = g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED); + if (thumb_failed) + goto next; - if (error != NULL) { - g_debug ("Can't read thumbnail pixbuf %s: %s\n", thumb_path, error->message); - goto out; - } - } else { - data->pixbuf = create_thumbnail (data); - } + thumb_path = g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH); - out: - g_clear_error (&error); - g_clear_object (&is); - g_clear_object (&thumb_file); - g_clear_object (&info); + if (thumb_path != NULL) { + thumb_file = g_file_new_for_path (thumb_path); + is = g_file_read (thumb_file, NULL, &error); - g_io_scheduler_job_send_to_mainloop_async (job, ensure_thumbnail_job_done, - data, NULL); + if (error != NULL) { + g_debug ("Can't read file %s: %s\n", thumb_path, error->message); + goto next; + } - return FALSE; -} + data->pixbuf = gdk_pixbuf_new_from_stream_at_scale (G_INPUT_STREAM (is), + 128, 128, TRUE, + NULL, &error); -static void -ensure_thumbnail (FontViewModel *self, - const gchar *path, - GtkTreeIter *iter) -{ - LoadThumbnailData *data; + if (error != NULL) { + g_debug ("Can't read thumbnail pixbuf %s: %s\n", thumb_path, error->message); + goto next; + } + } else { + data->pixbuf = create_thumbnail (data); + } - data = g_slice_new0 (LoadThumbnailData); - data->self = g_object_ref (self); - data->font_file = g_file_new_for_path (path); - data->font_path = g_strdup (path); - data->iter = *iter; + next: + g_clear_error (&error); + g_clear_object (&is); + g_clear_object (&thumb_file); + g_clear_object (&info); - g_io_scheduler_push_job (ensure_thumbnail_job, data, - NULL, G_PRIORITY_DEFAULT, NULL); + g_io_scheduler_job_send_to_mainloop_async (job, one_thumbnail_done, + data, NULL); + } + + g_list_free (thumbnails); + + return FALSE; } /* make sure the font list is valid */ @@ -296,6 +285,7 @@ ensure_font_list (FontViewModel *self) gint i; FcChar8 *file; gchar *font_name, *collation_key; + GList *thumbnails = NULL; if (self->priv->font_list) { FcFontSetDestroy (self->priv->font_list); @@ -321,6 +311,7 @@ ensure_font_list (FontViewModel *self) for (i = 0; i < self->priv->font_list->nfont; i++) { GtkTreeIter iter; + LoadThumbnailData *data; FcPatternGetString (self->priv->font_list->fonts[i], FC_FILE, 0, &file); font_name = font_utils_get_font_name_for_file (self->priv->library, (const gchar *) file); @@ -338,11 +329,20 @@ ensure_font_list (FontViewModel *self) COLUMN_COLLATION_KEY, collation_key, -1); - ensure_thumbnail (self, (const gchar *) file, &iter); + data = g_slice_new0 (LoadThumbnailData); + data->font_file = g_file_new_for_path (file); + data->font_path = g_strdup (file); + data->iter = iter; + data->self = g_object_ref (self); + + thumbnails = g_list_prepend (thumbnails, data); g_free (font_name); g_free (collation_key); } + + g_io_scheduler_push_job (ensure_thumbnails_job, thumbnails, + NULL, G_PRIORITY_DEFAULT, NULL); } static gboolean -- cgit v1.2.1