sxiv

simple X image viewer
git clone git://git.suckless.org/sxiv
Log | Files | Refs | LICENSE

commit 47af0dd7b5e154fb64d8b4d6c5302ba905055799
parent 9b9294bae67da4e0388e7c31d0063f4e114aa1f8
Author: Bert M√ľnnich <ber.t@posteo.de>
Date:   Sun,  4 Jan 2015 21:19:26 +0100

Cache out of view thumbnails in the background

Diffstat:
commands.c | 2+-
main.c | 24+++++++++++++++---------
thumbs.c | 32++++++++++++++++++++++----------
thumbs.h | 7++++---
types.h | 5+++--
5 files changed, 45 insertions(+), 25 deletions(-)

diff --git a/commands.c b/commands.c @@ -126,7 +126,7 @@ bool cg_reload_image(arg_t a) load_image(fileidx); } else { win_set_cursor(&win, CURSOR_WATCH); - if (!tns_load(&tns, fileidx, true)) { + if (!tns_load(&tns, fileidx, true, false)) { remove_file(fileidx, false); tns.dirty = true; } diff --git a/main.c b/main.c @@ -385,7 +385,10 @@ void update_info(void) r->p = r->buf; if (mode == MODE_THUMB) { if (tns.loadnext < tns.end) { - bar_put(l, "Loading... %0*d", fw, MAX(tns.loadnext, 1)); + bar_put(l, "Loading... %0*d", fw, tns.loadnext + 1); + ow_info = false; + } else if (tns.initnext < filecnt) { + bar_put(l, "Caching... %0*d", fw, tns.initnext + 1); ow_info = false; } else { ow_info = true; @@ -453,7 +456,7 @@ void reset_cursor(void) } } } else { - if (tns.loadnext < tns.end) + if (tns.loadnext < tns.end || tns.initnext < filecnt) cursor = CURSOR_WATCH; else cursor = CURSOR_ARROW; @@ -694,26 +697,29 @@ void run(void) int xfd; fd_set fds; struct timeval timeout; - bool discard, load_thumb, to_set; + bool discard, init_thumb, load_thumb, to_set; XEvent ev, nextev; while (true) { to_set = check_timeouts(&timeout); + init_thumb = mode == MODE_THUMB && tns.initnext < filecnt; load_thumb = mode == MODE_THUMB && tns.loadnext < tns.end; - if ((load_thumb || to_set || info.fd != -1) && + if ((init_thumb || load_thumb || to_set || info.fd != -1) && XPending(win.env.dpy) == 0) { if (load_thumb) { set_timeout(redraw, TO_REDRAW_THUMBS, false); - if (!tns_load(&tns, tns.loadnext, false)) { + if (!tns_load(&tns, tns.loadnext, false, false)) { remove_file(tns.loadnext, false); tns.dirty = true; } - while (tns.loadnext < tns.end && tns.thumbs[tns.loadnext].im != NULL) - tns.loadnext++; if (tns.loadnext >= tns.end) redraw(); + } else if (init_thumb) { + set_timeout(redraw, TO_REDRAW_THUMBS, false); + if (!tns_load(&tns, tns.initnext, false, true)) + remove_file(tns.initnext, false); } else { xfd = ConnectionNumber(win.env.dpy); FD_ZERO(&fds); @@ -899,8 +905,8 @@ int main(int argc, char **argv) if (options->thumb_mode) { mode = MODE_THUMB; tns_init(&tns, files, &filecnt, &fileidx, &win); - while (!tns_load(&tns, 0, false)) - remove_file(0, false); + while (!tns_load(&tns, fileidx, false, false)) + remove_file(fileidx, false); } else { mode = MODE_IMAGE; tns.thumbs = NULL; diff --git a/thumbs.c b/thumbs.c @@ -152,7 +152,7 @@ void tns_clean_cache(tns_t *tns) } -void tns_init(tns_t *tns, const fileinfo_t *files, const int *cnt, int *sel, +void tns_init(tns_t *tns, fileinfo_t *files, const int *cnt, int *sel, win_t *win) { int len; @@ -169,7 +169,8 @@ void tns_init(tns_t *tns, const fileinfo_t *files, const int *cnt, int *sel, } tns->files = files; tns->cnt = cnt; - tns->loadnext = tns->first = tns->end = tns->r_first = tns->r_end = 0; + tns->initnext = tns->loadnext = 0; + tns->first = tns->end = tns->r_first = tns->r_end = 0; tns->sel = sel; tns->win = win; tns->dirty = false; @@ -237,7 +238,7 @@ Imlib_Image tns_scale_down(Imlib_Image im, int dim) return im; } -bool tns_load(tns_t *tns, int n, bool force) +bool tns_load(tns_t *tns, int n, bool force, bool cache_only) { int w, h; int maxwh = thumb_sizes[ARRLEN(thumb_sizes)-1]; @@ -245,8 +246,8 @@ bool tns_load(tns_t *tns, int n, bool force) char *cfile; float zw, zh; thumb_t *t; + fileinfo_t *file; Imlib_Image im = NULL; - const fileinfo_t *file; if (tns == NULL || tns->thumbs == NULL) return false; @@ -261,6 +262,7 @@ bool tns_load(tns_t *tns, int n, bool force) if (t->im != NULL) { imlib_context_set_image(t->im); imlib_free_image(); + t->im = NULL; } if (!force) { @@ -345,10 +347,10 @@ bool tns_load(tns_t *tns, int n, bool force) warn("could not open image: %s", file->name); return false; } + imlib_context_set_image(im); if (!cache_hit) { #if HAVE_LIBEXIF - imlib_context_set_image(im); exif_auto_orientate(file); #endif im = tns_scale_down(im, maxwh); @@ -357,12 +359,22 @@ bool tns_load(tns_t *tns, int n, bool force) tns_cache_write(im, file->path, true); } - t->im = tns_scale_down(im, thumb_sizes[tns->zl]); - imlib_context_set_image(t->im); - t->w = imlib_image_get_width(); - t->h = imlib_image_get_height(); + if (cache_only) { + imlib_free_image_and_decache(); + } else { + t->im = tns_scale_down(im, thumb_sizes[tns->zl]); + imlib_context_set_image(t->im); + t->w = imlib_image_get_width(); + t->h = imlib_image_get_height(); + tns->dirty = true; + } + file->flags |= FF_TN_INIT; + + if (n == tns->initnext) + while (++tns->initnext < *tns->cnt && ((++file)->flags & FF_TN_INIT)); + if (n == tns->loadnext && !cache_only) + while (++tns->loadnext < tns->end && (++t)->im != NULL); - tns->dirty = true; return true; } diff --git a/thumbs.h b/thumbs.h @@ -34,10 +34,11 @@ typedef struct { } thumb_t; typedef struct { - const fileinfo_t *files; + fileinfo_t *files; thumb_t *thumbs; const int *cnt; int *sel; + int initnext; int loadnext; int first, end; int r_first, r_end; @@ -56,10 +57,10 @@ typedef struct { void tns_clean_cache(tns_t*); -void tns_init(tns_t*, const fileinfo_t*, const int*, int*, win_t*); +void tns_init(tns_t*, fileinfo_t*, const int*, int*, win_t*); void tns_free(tns_t*); -bool tns_load(tns_t*, int, bool); +bool tns_load(tns_t*, int, bool, bool); void tns_unload(tns_t*, int); void tns_render(tns_t*); diff --git a/types.h b/types.h @@ -65,8 +65,9 @@ typedef enum { } cursor_t; typedef enum { - FF_WARN = 1, - FF_MARK = 2 + FF_WARN = 1, + FF_MARK = 2, + FF_TN_INIT = 4 } fileflags_t; typedef struct {