Krolyxon
Commit eaa269b

Branches

Refs →

nsxiveaa269b

Revised thumbnail loading...

- Only load the thumbnails that are currently visible in the window
- Unload thumbnails that are leaving the visible area
- Much less memory needed, but scrolling is now slower
- This also unintentionally fixes issue #86
Author
Bert Münnich
Date
2014-09-25 20:57 +0200
Committer
Bert Münnich · 2014-09-26 10:31 +0200
Parent
52e56c8
Commit
eaa269b6cb486f83229cb0d3dc5f7e03d1c485bb

+71 −45

5 files changed

  1. M Makefile +1 −1
  2. M commands.c +2 −1
  3. M main.c +13 −20
  4. M thumbs.c +52 −20
  5. M thumbs.h +3 −3
M Makefile View
@@ -1,4 +1,4 @@
1−VERSION = git-20140911
1+VERSION = git-20140926
22
33 PREFIX = /usr/local
44 MANPREFIX = $(PREFIX)/share/man
M commands.c View
@@ -470,7 +470,8 @@ bool ct_reload_all(arg_t a)
470470 {
471471 tns_free(&tns);
472472 tns_init(&tns, files, filecnt, &fileidx, &win);
473− return false;
473+ tns.dirty = true;
474+ return true;
474475 }
475476
476477
M main.c View
@@ -368,14 +368,13 @@ void update_info(void)
368368 return;
369369 mark = files[fileidx].marked ? "+ " : "";
370370 if (mode == MODE_THUMB) {
371− if (tns.loadnext >= filecnt) {
372− n = snprintf(rt, rlen, "%s%0*d/%d", mark, fw, fileidx + 1, filecnt);
373− ow_info = true;
374− } else {
375− snprintf(lt, llen, "Loading... %0*d/%d", fw, tns.loadnext, filecnt);
376− rt[0] = '\0';
371+ if (tns.loadnext < tns.end) {
372+ snprintf(lt, llen, "Loading... %0*d", fw, tns.loadnext);
377373 ow_info = false;
374+ } else {
375+ ow_info = true;
378376 }
377+ n = snprintf(rt, rlen, "%s%0*d/%d", mark, fw, fileidx + 1, filecnt);
379378 } else {
380379 n = snprintf(rt, rlen, "%s", mark);
381380 if (img.ss.on)
@@ -439,7 +438,7 @@ void reset_cursor(void)
439438 }
440439 }
441440 } else {
442− if (tns.loadnext < filecnt)
441+ if (tns.loadnext < tns.end)
443442 cursor = CURSOR_WATCH;
444443 else
445444 cursor = CURSOR_ARROW;
@@ -531,7 +530,7 @@ void run_key_handler(const char *key, unsigned int mask)
531530 memcmp(&oldst->st_mtime, &newst.st_mtime, sizeof(newst.st_mtime)) != 0)
532531 {
533532 if (tns.thumbs != NULL) {
534− tns.thumbs[finfo[i].fn].loaded = false;
533+ tns_unload(&tns, finfo[i].fn);
535534 tns.loadnext = MIN(tns.loadnext, finfo[i].fn);
536535 }
537536 changed = true;
@@ -669,29 +668,24 @@ void run(void)
669668 int xfd;
670669 fd_set fds;
671670 struct timeval timeout;
672− bool discard, reload, to_set;
671+ bool discard, to_set;
673672 XEvent ev, nextev;
674673
675674 set_timeout(redraw, 25, false);
676675
677676 while (true) {
678− while (mode == MODE_THUMB && tns.loadnext < filecnt &&
677+ while (mode == MODE_THUMB && tns.loadnext < tns.end &&
679678 XPending(win.env.dpy) == 0)
680679 {
681680 /* load thumbnails */
682− reload = tns.loadnext != tns.cnt;
683681 set_timeout(redraw, TO_REDRAW_THUMBS, false);
684− if (tns_load(&tns, tns.loadnext, reload)) {
685− if (!reload)
686− tns.cnt++;
687− } else {
682+ if (!tns_load(&tns, tns.loadnext, false)) {
688683 remove_file(tns.loadnext, false);
689− if (reload)
690− tns.dirty = true;
684+ tns.dirty = true;
691685 }
692− while (tns.loadnext < filecnt && tns.thumbs[tns.loadnext].loaded)
686+ while (tns.loadnext < tns.end && tns.thumbs[tns.loadnext].im != NULL)
693687 tns.loadnext++;
694− if (tns.loadnext >= filecnt)
688+ if (tns.loadnext >= tns.end)
695689 redraw();
696690 else
697691 check_timeouts(NULL);
@@ -882,7 +876,6 @@ int main(int argc, char **argv)
882876 tns_init(&tns, files, filecnt, &fileidx, &win);
883877 while (!tns_load(&tns, 0, false))
884878 remove_file(0, false);
885− tns.cnt = 1;
886879 } else {
887880 mode = MODE_IMAGE;
888881 tns.thumbs = NULL;
M thumbs.c View
@@ -56,7 +56,7 @@ char* tns_cache_filepath(const char *filepath)
5656 return cfile;
5757 }
5858
59−Imlib_Image tns_cache_load(const char *filepath)
59+Imlib_Image tns_cache_load(const char *filepath, bool *outdated)
6060 {
6161 char *cfile;
6262 struct stat cstats, fstats;
@@ -68,8 +68,12 @@ Imlib_Image tns_cache_load(const char *filepath)
6868 return NULL;
6969
7070 if ((cfile = tns_cache_filepath(filepath)) != NULL) {
71− if (stat(cfile, &cstats) == 0 && cstats.st_mtime == fstats.st_mtime)
72− im = imlib_load_image(cfile);
71+ if (stat(cfile, &cstats) == 0) {
72+ if (cstats.st_mtime == fstats.st_mtime)
73+ im = imlib_load_image(cfile);
74+ else
75+ *outdated = true;
76+ }
7377 free(cfile);
7478 }
7579 return im;
@@ -165,8 +169,8 @@ void tns_init(tns_t *tns, const fileinfo_t *files, int cnt, int *sel, win_t *win
165169 tns->thumbs = NULL;
166170 }
167171 tns->files = files;
168− tns->cap = cnt;
169− tns->cnt = tns->loadnext = tns->first = 0;
172+ tns->cnt = cnt;
173+ tns->loadnext = tns->first = tns->end = tns->r_first = tns->r_end = 0;
170174 tns->sel = sel;
171175 tns->win = win;
172176 tns->dirty = false;
@@ -218,7 +222,7 @@ bool tns_load(tns_t *tns, int n, bool force)
218222
219223 if (tns == NULL || tns->thumbs == NULL)
220224 return false;
221− if (n < 0 || n >= tns->cap)
225+ if (n < 0 || n >= tns->cnt)
222226 return false;
223227 file = &tns->files[n];
224228 if (file->name == NULL || file->path == NULL)
@@ -231,7 +235,7 @@ bool tns_load(tns_t *tns, int n, bool force)
231235 imlib_free_image();
232236 }
233237
234− if (!force && (im = tns_cache_load(file->path)) != NULL) {
238+ if (!force && (im = tns_cache_load(file->path, &force)) != NULL) {
235239 cache_hit = true;
236240 } else {
237241 #if HAVE_LIBEXIF
@@ -323,11 +327,28 @@ bool tns_load(tns_t *tns, int n, bool force)
323327 if (!cache_hit)
324328 tns_cache_write(t, file, true);
325329
326− t->loaded = true;
327330 tns->dirty = true;
328331 return true;
329332 }
330333
334+void tns_unload(tns_t *tns, int n)
335+{
336+ thumb_t *t;
337+
338+ if (tns == NULL || tns->thumbs == NULL)
339+ return;
340+ if (n < 0 || n >= tns->cnt)
341+ return;
342+
343+ t = &tns->thumbs[n];
344+
345+ if (t->im != NULL) {
346+ imlib_context_set_image(t->im);
347+ imlib_free_image();
348+ t->im = NULL;
349+ }
350+}
351+
331352 void tns_check_view(tns_t *tns, bool scrolled)
332353 {
333354 int r;
@@ -385,20 +406,31 @@ void tns_render(tns_t *tns)
385406 if (r > 0)
386407 cnt -= r % tns->cols;
387408 }
388−
389409 r = cnt % tns->cols ? 1 : 0;
390410 tns->x = x = (win->w - MIN(cnt, tns->cols) * thumb_dim) / 2 + 5;
391411 tns->y = y = (win->h - (cnt / tns->cols + r) * thumb_dim) / 2 + 5;
412+ tns->loadnext = tns->cnt;
413+ tns->end = tns->first + cnt;
392414
393− for (i = 0; i < cnt; i++) {
394− t = &tns->thumbs[tns->first + i];
395− t->x = x + (THUMB_SIZE - t->w) / 2;
396− t->y = y + (THUMB_SIZE - t->h) / 2;
397− imlib_context_set_image(t->im);
398− imlib_render_image_part_on_drawable_at_size(0, 0, t->w, t->h,
399− t->x, t->y, t->w, t->h);
400− if (tns->files[tns->first + i].marked)
401− tns_mark(tns, tns->first + i, true);
415+ for (i = tns->r_first; i < tns->r_end; i++) {
416+ if ((i < tns->first || i >= tns->end) && tns->thumbs[i].im != NULL)
417+ tns_unload(tns, i);
418+ }
419+ tns->r_first = tns->first;
420+ tns->r_end = tns->end;
421+
422+ for (i = tns->first; i < tns->end; i++) {
423+ t = &tns->thumbs[i];
424+ if (t->im != NULL) {
425+ t->x = x + (THUMB_SIZE - t->w) / 2;
426+ t->y = y + (THUMB_SIZE - t->h) / 2;
427+ imlib_context_set_image(t->im);
428+ imlib_render_image_on_drawable_at_size(t->x, t->y, t->w, t->h);
429+ if (tns->files[i].marked)
430+ tns_mark(tns, i, true);
431+ } else {
432+ tns->loadnext = MIN(tns->loadnext, i);
433+ }
402434 if ((i + 1) % tns->cols == 0) {
403435 x = tns->x;
404436 y += thumb_dim;
@@ -415,7 +447,7 @@ void tns_mark(tns_t *tns, int n, bool mark)
415447 if (tns == NULL || tns->thumbs == NULL || tns->win == NULL)
416448 return;
417449
418− if (n >= 0 && n < tns->cnt) {
450+ if (n >= 0 && n < tns->cnt && tns->thumbs[n].im != NULL) {
419451 win_t *win = tns->win;
420452 thumb_t *t = &tns->thumbs[n];
421453 unsigned long col = win->fullscreen ? win->fscol : win->bgcol;
@@ -440,7 +472,7 @@ void tns_highlight(tns_t *tns, int n, bool hl)
440472 if (tns == NULL || tns->thumbs == NULL || tns->win == NULL)
441473 return;
442474
443− if (n >= 0 && n < tns->cnt) {
475+ if (n >= 0 && n < tns->cnt && tns->thumbs[n].im != NULL) {
444476 win_t *win = tns->win;
445477 thumb_t *t = &tns->thumbs[n];
446478 unsigned long col;
M thumbs.h View
@@ -31,16 +31,15 @@ typedef struct {
3131 int h;
3232 int x;
3333 int y;
34− bool loaded;
3534 } thumb_t;
3635
3736 typedef struct {
3837 const fileinfo_t *files;
3938 thumb_t *thumbs;
40− int cap;
4139 int cnt;
4240 int loadnext;
43− int first;
41+ int first, end;
42+ int r_first, r_end;
4443 int *sel;
4544
4645 win_t *win;
@@ -58,6 +57,7 @@ void tns_init(tns_t*, const fileinfo_t*, int, int*, win_t*);
5857 void tns_free(tns_t*);
5958
6059 bool tns_load(tns_t*, int, bool);
60+void tns_unload(tns_t*, int);
6161
6262 void tns_render(tns_t*);
6363 void tns_mark(tns_t*, int, bool);