Update Version, Release, BuildRequires, stage 'files' Delete 4 patches, modify the left 6 patches
247 lines
7.5 KiB
Diff
247 lines
7.5 KiB
Diff
From d8a9c8c3526980e576e8d61d033cd983562b07d3 Mon Sep 17 00:00:00 2001
|
|
From: Benjamin Berg <bberg@redhat.com>
|
|
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
|
|
---
|
|
diff --git a/panels/background/bg-pictures-source.c b/panels/background/bg-pictures-source.c
|
|
index 3a3027b..3b955bb 100644
|
|
--- a/panels/background/bg-pictures-source.c
|
|
+++ b/panels/background/bg-pictures-source.c
|
|
@@ -45,12 +45,26 @@ struct _BgPicturesSource
|
|
|
|
CcBackgroundGriloMiner *grl_miner;
|
|
|
|
+ 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[] = {
|
|
@@ -72,6 +86,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)
|
|
{
|
|
@@ -83,6 +177,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_OBJECT_CLASS (bg_pictures_source_parent_class)->dispose (object);
|
|
@@ -206,6 +303,10 @@ 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;
|
|
@@ -227,7 +328,9 @@ 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);
|
|
- return;
|
|
+
|
|
+ add_processing_finished (bg_source);
|
|
+ return;
|
|
}
|
|
|
|
/* Process embedded orientation */
|
|
@@ -262,6 +365,8 @@ picture_scaled (GObject *source_object,
|
|
GINT_TO_POINTER (TRUE));
|
|
|
|
g_clear_pointer (&surface, cairo_surface_destroy);
|
|
+
|
|
+ add_processing_finished (bg_source);
|
|
}
|
|
|
|
static void
|
|
@@ -286,6 +391,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;
|
|
@@ -339,6 +447,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;
|
|
}
|
|
}
|
|
@@ -378,10 +490,11 @@ bg_pictures_source_get_cache_file (void)
|
|
}
|
|
|
|
static gboolean
|
|
-add_single_file (BgPicturesSource *bg_source,
|
|
- GFile *file,
|
|
- const gchar *content_type,
|
|
- guint64 mtime)
|
|
+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;
|
|
@@ -480,6 +593,11 @@ add_single_file (BgPicturesSource *bg_source,
|
|
retval = TRUE;
|
|
|
|
out:
|
|
+
|
|
+ /* Async processing is happening. */
|
|
+ if (!retval)
|
|
+ add_processing_finished (bg_source);
|
|
+
|
|
return retval;
|
|
}
|
|
|
|
@@ -493,7 +611,7 @@ add_single_file_from_info (BgPicturesSource *bg_source,
|
|
|
|
content_type = g_file_info_get_content_type (info);
|
|
mtime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
|
|
- return add_single_file (bg_source, file, content_type, mtime);
|
|
+ return add_single_file (bg_source, file, content_type, mtime, NULL);
|
|
}
|
|
|
|
static gboolean
|
|
@@ -518,7 +636,7 @@ add_single_file_from_media (BgPicturesSource *bg_source,
|
|
else
|
|
mtime_unix = g_get_real_time () / G_USEC_PER_SEC;
|
|
|
|
- return add_single_file (bg_source, file, content_type, (guint64) mtime_unix);
|
|
+ return add_single_file (bg_source, file, content_type, (guint64) mtime_unix, NULL);
|
|
}
|
|
|
|
gboolean
|
|
@@ -828,6 +946,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 ();
|