[gnome-music] albumartcache: Make albumart fetching truly asynchronous
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-music] albumartcache: Make albumart fetching truly asynchronous
- Date: Sun, 3 Jan 2016 18:25:22 +0000 (UTC)
commit 855b710354402357064e5442da51fb25aa202b9d
Author: Carlos Garnacho <carlosg gnome org>
Date: Sat Dec 26 21:27:39 2015 +0100
albumartcache: Make albumart fetching truly asynchronous
Despite spawning this into a separate thread, this is still processed
quasi-synchronously, delaying the whole insertion.
Instead, use GIO/GdkPixbuf asynchronous APIs to load pixbufs, being set
as a low priority idle, the actual pixbuf loading will be deferred until
the UI is shown. this also means the "..." loading icons will be visible.
https://bugzilla.gnome.org/show_bug.cgi?id=760033
gnomemusic/albumArtCache.py | 55 +++++++++++++++++++++++++++++++++---------
1 files changed, 43 insertions(+), 12 deletions(-)
---
diff --git a/gnomemusic/albumArtCache.py b/gnomemusic/albumArtCache.py
index d1bd96a..86f502a 100644
--- a/gnomemusic/albumArtCache.py
+++ b/gnomemusic/albumArtCache.py
@@ -83,7 +83,6 @@ class AlbumArtCache(GObject.GObject):
instance = None
blacklist = {}
itr_queue = []
- threading_lock = Lock()
default_icons_cache = {}
default_icon_width = 256
@@ -192,8 +191,8 @@ class AlbumArtCache(GObject.GObject):
pass
# Scale the image down
- orig_icon =
self.default_icons_cache[self.default_icon_width][self.default_icon_height][is_loading].copy()
- final_icon = orig_icon.scale_simple(width, height, GdkPixbuf.InterpType.BILINEAR)
+ orig_icon = self.default_icons_cache[self.default_icon_width][self.default_icon_height][is_loading]
+ final_icon = orig_icon.scale_simple(width, height, GdkPixbuf.InterpType.NEAREST)
# Create a cache reference
if width not in self.default_icons_cache:
@@ -211,17 +210,49 @@ class AlbumArtCache(GObject.GObject):
try:
# Make sure we don't lookup the same iterators several times
- with self.threading_lock:
- if itr:
- if itr.user_data in self.itr_queue:
- return
- self.itr_queue.append(itr.user_data)
+ if itr:
+ if itr.user_data in self.itr_queue:
+ return
+ self.itr_queue.append(itr.user_data)
- t = Thread(target=self.lookup_worker, args=(item, width, height, callback, itr, artist, album))
- THREAD_QUEUE.append(t)
- self.emit('thread-added', len(THREAD_QUEUE) - 1)
+ [success, thumb_file] = MediaArt.get_file(artist, album, "album")
+
+ if success == False:
+ self.finish(item, None, None, callback, itr, width, height)
+ return
+
+ if not thumb_file.query_exists():
+ GLib.idle_add(self.cached_thumb_not_found, item, width, height, thumb_file.get_path(),
callback, itr, artist, album)
+ return
+ stream = thumb_file.read_async(GLib.PRIORITY_LOW, None, self.stream_open,
+ [item, width, height, thumb_file, callback, itr, artist, album])
+ except Exception as e:
+ logger.warn("Error: %s, %s", e.__class__, e)
+
+ @log
+ def stream_open(self, thumb_file, result, arguments):
+ (item, width, height, thumb_file, callback, itr, artist, album) = arguments
+
+ try:
+ width = width or -1
+ height = height or -1
+ stream = thumb_file.read_finish (result)
+ GdkPixbuf.Pixbuf.new_from_stream_at_scale_async(stream, width, height, True, None,
self.pixbuf_loaded,
+ [item, thumb_file, callback, itr, artist, album])
+ except Exception as e:
+ logger.warn("Error: %s, %s", e.__class__, e)
+ self.finish(item, None, None, callback, itr, width, height)
+
+ @log
+ def pixbuf_loaded(self, stream, result, arguments):
+ (item, thumb_file, callback, itr, artist, album) = arguments
+
+ try:
+ pixbuf = GdkPixbuf.Pixbuf.new_from_stream_finish (result)
+ self.finish(item, _make_icon_frame(pixbuf), thumb_file.get_path(), callback, itr, artist, album)
except Exception as e:
logger.warn("Error: %s, %s", e.__class__, e)
+ self.finish(item, None, None, callback, itr, None, None)
@log
def lookup_worker(self, item, width, height, callback, itr, artist, album):
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]