Compare commits

..

No commits in common. "a5ebc697add091664a98ba1c201767abdf577c63" and "604594a8f1d048b516120ba98eba71302e2043b4" have entirely different histories.

View File

@ -92,8 +92,7 @@ struct _FivBrowser {
Thumbnailer *thumbnailers; ///< Parallelized thumbnailers Thumbnailer *thumbnailers; ///< Parallelized thumbnailers
size_t thumbnailers_len; ///< Thumbnailers array size size_t thumbnailers_len; ///< Thumbnailers array size
GQueue thumbnailers_queue_1; ///< Queued up Entry pointers, hi-prio GQueue thumbnailers_queue; ///< Queued up Entry pointers
GQueue thumbnailers_queue_2; ///< Queued up Entry pointers, lo-prio
GdkCursor *pointer; ///< Cached pointer cursor GdkCursor *pointer; ///< Cached pointer cursor
cairo_pattern_t *glow; ///< CAIRO_FORMAT_A8 mask for corners cairo_pattern_t *glow; ///< CAIRO_FORMAT_A8 mask for corners
@ -743,7 +742,7 @@ thumbnailer_reprocess_entry(FivBrowser *self, GBytes *output, Entry *entry)
if ((flags & FIV_IO_SERIALIZE_LOW_QUALITY)) { if ((flags & FIV_IO_SERIALIZE_LOW_QUALITY)) {
cairo_surface_set_user_data(entry->thumbnail, &fiv_thumbnail_key_lq, cairo_surface_set_user_data(entry->thumbnail, &fiv_thumbnail_key_lq,
(void *) (intptr_t) 1, NULL); (void *) (intptr_t) 1, NULL);
g_queue_push_tail(&self->thumbnailers_queue_2, entry); g_queue_push_tail(&self->thumbnailers_queue, entry);
} }
entry_set_surface_user_data(entry); entry_set_surface_user_data(entry);
@ -797,21 +796,13 @@ on_thumbnailer_ready(GObject *object, GAsyncResult *res, gpointer user_data)
thumbnailer_next(t); thumbnailer_next(t);
} }
// TODO(p): Try to keep the minions alive (stdout will be a problem).
static gboolean static gboolean
thumbnailer_next(Thumbnailer *t) thumbnailer_next(Thumbnailer *t)
{ {
// Already have something to do, not a failure. // TODO(p): Try to keep the minions alive (stdout will be a problem).
if (t->target)
return TRUE;
// They could have been removed via post-reload changes in the model.
FivBrowser *self = t->self; FivBrowser *self = t->self;
do { if (!(t->target = g_queue_pop_head(&self->thumbnailers_queue)))
if (!(t->target = g_queue_pop_head(&self->thumbnailers_queue_1)) && return FALSE;
!(t->target = g_queue_pop_head(&self->thumbnailers_queue_2)))
return FALSE;
} while (t->target->removed);
// Case analysis: // Case analysis:
// - We haven't found any thumbnail for the entry at all // - We haven't found any thumbnail for the entry at all
@ -848,8 +839,7 @@ thumbnailer_next(Thumbnailer *t)
static void static void
thumbnailers_abort(FivBrowser *self) thumbnailers_abort(FivBrowser *self)
{ {
g_queue_clear(&self->thumbnailers_queue_1); g_queue_clear(&self->thumbnailers_queue);
g_queue_clear(&self->thumbnailers_queue_2);
for (size_t i = 0; i < self->thumbnailers_len; i++) { for (size_t i = 0; i < self->thumbnailers_len; i++) {
Thumbnailer *t = self->thumbnailers + i; Thumbnailer *t = self->thumbnailers + i;
@ -865,35 +855,35 @@ thumbnailers_abort(FivBrowser *self)
} }
static void static void
thumbnailers_enqueue(FivBrowser *self, Entry *entry) thumbnailers_start(FivBrowser *self)
{ {
if (!entry->removed) { thumbnailers_abort(self);
if (!self->model)
return;
GQueue lq = G_QUEUE_INIT;
for (guint i = 0; i < self->entries->len; i++) {
Entry *entry = self->entries->pdata[i];
if (entry->removed)
continue;
if (entry->icon) if (entry->icon)
g_queue_push_tail(&self->thumbnailers_queue_1, entry); g_queue_push_tail(&self->thumbnailers_queue, entry);
else if (cairo_surface_get_user_data( else if (cairo_surface_get_user_data(
entry->thumbnail, &fiv_thumbnail_key_lq)) entry->thumbnail, &fiv_thumbnail_key_lq))
g_queue_push_tail(&self->thumbnailers_queue_2, entry); g_queue_push_tail(&lq, entry);
}
while (!g_queue_is_empty(&lq)) {
g_queue_push_tail_link(
&self->thumbnailers_queue, g_queue_pop_head_link(&lq));
} }
}
static void
thumbnailers_deploy(FivBrowser *self)
{
for (size_t i = 0; i < self->thumbnailers_len; i++) { for (size_t i = 0; i < self->thumbnailers_len; i++) {
if (!thumbnailer_next(self->thumbnailers + i)) if (!thumbnailer_next(self->thumbnailers + i))
break; break;
} }
} }
static void
thumbnailers_restart(FivBrowser *self)
{
thumbnailers_abort(self);
for (guint i = 0; i < self->entries->len; i++)
thumbnailers_enqueue(self, self->entries->pdata[i]);
thumbnailers_deploy(self);
}
// --- Boilerplate ------------------------------------------------------------- // --- Boilerplate -------------------------------------------------------------
G_DEFINE_TYPE_EXTENDED(FivBrowser, fiv_browser, GTK_TYPE_WIDGET, 0, G_DEFINE_TYPE_EXTENDED(FivBrowser, fiv_browser, GTK_TYPE_WIDGET, 0,
@ -1014,7 +1004,7 @@ set_item_size(FivBrowser *self, FivThumbnailSize size)
g_hash_table_remove_all(self->thumbnail_cache); g_hash_table_remove_all(self->thumbnail_cache);
reload_thumbnails(self); reload_thumbnails(self);
thumbnailers_restart(self); thumbnailers_start(self);
g_object_notify_by_pspec( g_object_notify_by_pspec(
G_OBJECT(self), browser_properties[PROP_THUMBNAIL_SIZE]); G_OBJECT(self), browser_properties[PROP_THUMBNAIL_SIZE]);
@ -1882,8 +1872,7 @@ fiv_browser_init(FivBrowser *self)
g_malloc0_n(self->thumbnailers_len, sizeof *self->thumbnailers); g_malloc0_n(self->thumbnailers_len, sizeof *self->thumbnailers);
for (size_t i = 0; i < self->thumbnailers_len; i++) for (size_t i = 0; i < self->thumbnailers_len; i++)
self->thumbnailers[i].self = self; self->thumbnailers[i].self = self;
g_queue_init(&self->thumbnailers_queue_1); g_queue_init(&self->thumbnailers_queue);
g_queue_init(&self->thumbnailers_queue_2);
set_item_size(self, FIV_THUMBNAIL_SIZE_NORMAL); set_item_size(self, FIV_THUMBNAIL_SIZE_NORMAL);
self->show_labels = FALSE; self->show_labels = FALSE;
@ -1928,9 +1917,8 @@ on_model_reloaded(FivIoModel *model, FivBrowser *self)
fiv_browser_select(self, selected_uri); fiv_browser_select(self, selected_uri);
g_free(selected_uri); g_free(selected_uri);
// Restarting thumbnailers is critical, because they keep Entry pointers.
reload_thumbnails(self); reload_thumbnails(self);
thumbnailers_restart(self); thumbnailers_start(self);
} }
static void static void
@ -1945,8 +1933,8 @@ on_model_changed(FivIoModel *model, FivIoModelEntry *old, FivIoModelEntry *new,
g_ptr_array_add(self->entries, entry); g_ptr_array_add(self->entries, entry);
reload_one_thumbnail(self, entry); reload_one_thumbnail(self, entry);
thumbnailers_enqueue(self, entry); // TODO(p): Try to add to thumbnailer queue if already started.
thumbnailers_deploy(self); thumbnailers_start(self);
return; return;
} }
@ -1972,9 +1960,8 @@ on_model_changed(FivIoModel *model, FivIoModelEntry *old, FivIoModelEntry *new,
// so that there's no jumping around. Or, a bit more properly, // so that there's no jumping around. Or, a bit more properly,
// move the thumbnail cache entry to the new URI. // move the thumbnail cache entry to the new URI.
reload_one_thumbnail(self, found); reload_one_thumbnail(self, found);
// TODO(p): Rather cancel the entry in any running thumbnailer, // TODO(p): Try to add to thumbnailer queue if already started.
// remove it from queues, and _enqueue() + _deploy(). thumbnailers_start(self);
thumbnailers_restart(self);
} else { } else {
found->removed = TRUE; found->removed = TRUE;
gtk_widget_queue_draw(GTK_WIDGET(self)); gtk_widget_queue_draw(GTK_WIDGET(self));