From e5d95255c0aa59e246ff7a31fe2c5b792ad02a98 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Oct 10 2018 09:32:33 +0000 Subject: Add patch to improve background loading (#1631002) This is a patch from upstream which needs to be reworked to be mergable. However, it does improve the situation a lot, fixing crashes and causing gnome-control-center to not lock up completely. --- diff --git a/0002-background-Add-queue-to-load-4-pictures-at-a-time.patch b/0002-background-Add-queue-to-load-4-pictures-at-a-time.patch new file mode 100644 index 0000000..aaf8dfa --- /dev/null +++ b/0002-background-Add-queue-to-load-4-pictures-at-a-time.patch @@ -0,0 +1,232 @@ +From d8a9c8c3526980e576e8d61d033cd983562b07d3 Mon Sep 17 00:00:00 2001 +From: Benjamin Berg +Date: Mon, 1 Oct 2018 20:36:05 +0200 +Subject: [PATCH] background: Add queue to load 4 pictures at a time + +We need to process the pictures sequentially rather than trying to +thumbnail all of them in parallel. This commit adds a simple task queue +from which 4 tasks at will be processed at the same time. + +Fixes #191 +--- + panels/background/bg-pictures-source.c | 128 ++++++++++++++++++++++++- + 1 file changed, 123 insertions(+), 5 deletions(-) + +diff --git a/panels/background/bg-pictures-source.c b/panels/background/bg-pictures-source.c +index a37682d63..2e43ae84a 100644 +--- a/panels/background/bg-pictures-source.c ++++ b/panels/background/bg-pictures-source.c +@@ -47,12 +47,26 @@ struct _BgPicturesSource + + GnomeDesktopThumbnailFactory *thumb_factory; + ++ GQueue add_queue; ++ gint adds_running; ++ + GFileMonitor *picture_dir_monitor; + GFileMonitor *cache_dir_monitor; + + GHashTable *known_items; + }; + ++#define MAX_PARALLEL_ADD 4 ++ ++typedef struct { ++ BgPicturesSource *bg_source; ++ GFile *file; ++ gchar *content_type; ++ guint64 mtime; ++ GtkTreeRowReference **ret_row_ref; ++ GCancellable *cancellable; ++} AddQueueData; ++ + G_DEFINE_TYPE (BgPicturesSource, bg_pictures_source, BG_TYPE_SOURCE) + + const char * const content_types[] = { +@@ -74,6 +88,86 @@ static char *bg_pictures_source_get_unique_filename (const char *uri); + + static void picture_opened_for_read (GObject *source_object, GAsyncResult *res, gpointer user_data); + ++static gboolean add_single_file_real (BgPicturesSource *bg_source, ++ GFile *file, ++ const gchar *content_type, ++ guint64 mtime, ++ GtkTreeRowReference **ret_row_ref); ++ ++static void ++add_queue_data_free (AddQueueData *data) ++{ ++ g_clear_object (&data->file); ++ g_clear_object (&data->cancellable); ++ g_free (data->content_type); ++ g_free (data); ++} ++ ++static gboolean ++add_single_file_idle (gpointer user_data) ++{ ++ AddQueueData *data = (AddQueueData*) user_data; ++ ++ if (!g_cancellable_is_cancelled (data->cancellable)) ++ add_single_file_real (data->bg_source, data->file, data->content_type, ++ data->mtime, data->ret_row_ref); ++ add_queue_data_free (data); ++ ++ return FALSE; ++} ++ ++static void ++ensure_add_processing (BgPicturesSource *bg_source) ++{ ++ while (bg_source->adds_running < MAX_PARALLEL_ADD) ++ { ++ AddQueueData *data = g_queue_pop_head (&bg_source->add_queue); ++ ++ /* Nothing left to process */ ++ if (!data) ++ return; ++ ++ g_idle_add (add_single_file_idle, data); ++ ++ bg_source->adds_running += 1; ++ } ++} ++ ++static void ++add_processing_finished (BgPicturesSource *bg_source) ++{ ++ g_assert (bg_source->adds_running > 0); ++ ++ bg_source->adds_running -= 1; ++ ++ ensure_add_processing (bg_source); ++} ++ ++static gboolean ++add_single_file (BgPicturesSource *bg_source, ++ GFile *file, ++ const gchar *content_type, ++ guint64 mtime, ++ GtkTreeRowReference **ret_row_ref) ++{ ++ AddQueueData *data = g_new0 (AddQueueData, 1); ++ ++ data->bg_source = bg_source; ++ data->file = g_object_ref (file); ++ data->content_type = g_strdup (content_type); ++ data->mtime = mtime; ++ data->ret_row_ref = ret_row_ref; ++ data->cancellable = g_object_ref (bg_source->cancellable); ++ ++ g_queue_push_tail (&bg_source->add_queue, data); ++ ++ ensure_add_processing (bg_source); ++ ++ /* Just return TRUE. */ ++ return TRUE; ++} ++ ++ + static void + bg_pictures_source_dispose (GObject *object) + { +@@ -85,6 +179,9 @@ bg_pictures_source_dispose (GObject *object) + g_clear_object (&source->cancellable); + } + ++ g_queue_foreach (&source->add_queue, (GFunc) add_queue_data_free, NULL); ++ g_queue_clear (&source->add_queue); ++ + g_clear_object (&source->grl_miner); + g_clear_object (&source->thumb_factory); + +@@ -190,6 +287,9 @@ picture_scaled (GObject *source_object, + { + g_warning ("Failed to load image: %s", error->message); + remove_placeholder (BG_PICTURES_SOURCE (user_data), item); ++ ++ bg_source = BG_PICTURES_SOURCE (user_data); ++ add_processing_finished (bg_source); + } + + return; +@@ -211,6 +311,8 @@ picture_scaled (GObject *source_object, + { + g_debug ("Ignored URL '%s' as it's a screenshot from gnome-screenshot", uri); + remove_placeholder (BG_PICTURES_SOURCE (user_data), item); ++ ++ add_processing_finished (bg_source); + return; + } + +@@ -264,6 +366,8 @@ picture_scaled (GObject *source_object, + GINT_TO_POINTER (TRUE)); + + g_clear_pointer (&surface, (GDestroyNotify) cairo_surface_destroy); ++ ++ add_processing_finished (bg_source); + } + + static void +@@ -288,6 +392,9 @@ picture_opened_for_read (GObject *source_object, + g_autofree gchar *filename = g_file_get_path (G_FILE (source_object)); + g_warning ("Failed to load picture '%s': %s", filename, error->message); + remove_placeholder (BG_PICTURES_SOURCE (user_data), item); ++ ++ bg_source = BG_PICTURES_SOURCE (user_data); ++ add_processing_finished (bg_source); + } + + return; +@@ -341,6 +448,10 @@ picture_copied_for_read (GObject *source_object, + + uri = g_file_get_uri (thumbnail_file); + g_warning ("Failed to download '%s': %s", uri, error->message); ++ ++ bg_source = BG_PICTURES_SOURCE (user_data); ++ add_processing_finished (bg_source); ++ + return; + } + } +@@ -441,11 +552,11 @@ bg_pictures_source_get_cache_file (void) + } + + static gboolean +-add_single_file (BgPicturesSource *bg_source, +- GFile *file, +- const gchar *content_type, +- guint64 mtime, +- GtkTreeRowReference **ret_row_ref) ++add_single_file_real (BgPicturesSource *bg_source, ++ GFile *file, ++ const gchar *content_type, ++ guint64 mtime, ++ GtkTreeRowReference **ret_row_ref) + { + g_autoptr(CcBackgroundItem) item = NULL; + CcBackgroundItemFlags flags = 0; +@@ -573,6 +684,11 @@ add_single_file (BgPicturesSource *bg_source, + } + gtk_tree_path_free (path); + g_clear_pointer (&surface, (GDestroyNotify) cairo_surface_destroy); ++ ++ /* Async processing is happening. */ ++ if (!retval) ++ add_processing_finished (bg_source); ++ + return retval; + } + +@@ -955,6 +1071,8 @@ bg_pictures_source_init (BgPicturesSource *self) + (GDestroyNotify) g_free, + NULL); + ++ g_queue_init (&self->add_queue); ++ + pictures_path = g_get_user_special_dir (G_USER_DIRECTORY_PICTURES); + if (pictures_path == NULL) + pictures_path = g_get_home_dir (); +-- +2.19.0 + diff --git a/gnome-control-center.spec b/gnome-control-center.spec index 511410a..0222d79 100644 --- a/gnome-control-center.spec +++ b/gnome-control-center.spec @@ -10,7 +10,7 @@ Name: gnome-control-center Version: 3.30.1 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Utilities to configure the GNOME desktop License: GPLv2+ and CC-BY-SA @@ -21,6 +21,7 @@ Source0: https://download.gnome.org/sources/gnome-control-center/3.30/gno Patch0: distro-logo.patch # Backported from upstream Patch1: 0001-online-accounts-Track-the-lifecycle-of-CcGoaPanel-ac.patch +Patch2: 0002-background-Add-queue-to-load-4-pictures-at-a-time.patch BuildRequires: chrpath BuildRequires: cups-devel @@ -191,6 +192,11 @@ chrpath --delete $RPM_BUILD_ROOT%{_bindir}/gnome-control-center %dir %{_datadir}/gnome/wm-properties %changelog +* Wed Oct 10 2018 Benjamin Berg - 3.30.1-3 +- Add patch to improve background loading. The patch is not acceptable + upstream as is, but is also a good improvement on the current situation + (#1631002) + * Sun Oct 07 2018 Kalev Lember - 3.30.1-2 - Backport an upstream fix for a crash in the online accounts panel