Commit 66e625cb authored by Jim Nelson's avatar Jim Nelson

Small update to the photo viewer and pixbuf cache, to better prioritize background fetches.

parent 7a2dc435
......@@ -856,9 +856,12 @@ public abstract class EditingHostPage : SinglePhotoPage {
}
private void prefetch_neighbors(ViewCollection controller, Photo photo) {
cache.prefetch(photo, BackgroundJob.JobPriority.HIGHEST);
master_cache.prefetch(photo, BackgroundJob.JobPriority.LOW);
PixbufCache.PixbufCacheBatch normal_batch = new PixbufCache.PixbufCacheBatch();
PixbufCache.PixbufCacheBatch master_batch = new PixbufCache.PixbufCacheBatch();
normal_batch.set(BackgroundJob.JobPriority.HIGHEST, photo);
master_batch.set(BackgroundJob.JobPriority.LOW, photo);
DataSource next_source, prev_source;
if (!controller.get_immediate_neighbors(photo, out next_source, out prev_source))
return;
......@@ -874,9 +877,12 @@ public abstract class EditingHostPage : SinglePhotoPage {
if (neighbor.equals(next) || neighbor.equals(prev))
priority = BackgroundJob.JobPriority.HIGH;
cache.prefetch(neighbor, priority);
master_cache.prefetch(neighbor, BackgroundJob.JobPriority.LOWEST);
normal_batch.set(priority, neighbor);
master_batch.set(BackgroundJob.JobPriority.LOWEST, neighbor);
}
cache.prefetch_batch(normal_batch);
master_cache.prefetch_batch(master_batch);
}
// Cancels prefetches of old neighbors, but does not cancel them if they are the new
......
......@@ -12,6 +12,12 @@ public class PixbufCache : Object {
MASTER
}
public class PixbufCacheBatch : Gee.TreeMultiMap<BackgroundJob.JobPriority, Photo> {
public PixbufCacheBatch() {
base (BackgroundJob.JobPriority.compare_func);
}
}
private abstract class FetchJob : BackgroundJob {
public BackgroundJob.JobPriority priority;
public Photo photo;
......@@ -95,7 +101,7 @@ public class PixbufCache : Object {
assert(max_count > 0);
if (background_workers == null)
background_workers = new Workers(Workers.threads_per_cpu(1), false);
background_workers = new Workers(Workers.thread_per_cpu_minus_one(), false);
// monitor changes in the photos to discard from cache
sources.item_altered.connect(on_source_altered);
......@@ -204,6 +210,14 @@ public class PixbufCache : Object {
prefetch(photo, priority, force);
}
// Like prefetch_many, but allows for priorities to be set for each photo
public void prefetch_batch(PixbufCacheBatch batch, bool force = false) {
foreach (BackgroundJob.JobPriority priority in batch.get_keys()) {
foreach (Photo photo in batch.get(priority))
prefetch(photo, priority, force);
}
}
public bool cancel_prefetch(Photo photo) {
FetchJob job = in_progress.get(photo);
if (job == null)
......
......@@ -275,10 +275,13 @@ public class ThumbnailCache : Object {
// and slow down scrolling operations ... this delays reporting them, and only then reporting
// them in one aggregate sum
private static void schedule_debug() {
#if MONITOR_THUMBNAIL_CACHE
debug_scheduler.priority_after_timeout(Priority.LOW, 500, true);
#endif
}
private static void report_cycle() {
#if MONITOR_THUMBNAIL_CACHE
if (cycle_fetched_thumbnails > 0) {
debug("%d thumbnails fetched into memory", cycle_fetched_thumbnails);
cycle_fetched_thumbnails = 0;
......@@ -301,6 +304,7 @@ public class ThumbnailCache : Object {
cache.size.get_scale(), cache.cache_lru.size, cache.cached_bytes,
cache.max_cached_bytes, avg);
}
#endif
}
private Gdk.Pixbuf _fetch(ThumbnailSource source) throws Error {
......
......@@ -184,6 +184,10 @@ public abstract class BackgroundJob {
public int compare(JobPriority other) {
return (int) other - (int) this;
}
public static int compare_func(void *a, void *b) {
return (int) b - (int) a;
}
}
private class NotificationJob {
......@@ -368,6 +372,12 @@ public class Workers {
return number_of_processors() * per;
}
// This is useful when the intent is for the worker threads to use all the CPUs minus one for
// the main/UI thread. (No guarantees, of course.)
public static int thread_per_cpu_minus_one() ensures (result > 0) {
return (number_of_processors() - 1).clamp(1, int.MAX);
}
// Enqueues a BackgroundJob for work in a thread context. BackgroundJob.execute() is called
// within the thread's context, while its CompletionCallback is called within the Gtk event loop.
public void enqueue(BackgroundJob job) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment