Mercurial > geeqie.yaz
changeset 846:8911a4f0e56c
simple cache for loaded pixbufs
author | nadvornik |
---|---|
date | Sat, 21 Jun 2008 16:00:13 +0000 |
parents | 06929cbcd796 |
children | 77fc0ea3457d |
files | src/filecache.c src/filecache.h src/filedata.c src/image.c src/typedefs.h |
diffstat | 5 files changed, 84 insertions(+), 368 deletions(-) [+] |
line wrap: on
line diff
--- a/src/filecache.c Sat Jun 21 11:05:55 2008 +0000 +++ b/src/filecache.c Sat Jun 21 16:00:13 2008 +0000 @@ -74,3 +74,16 @@ fc->release(last_fd); file_data_unref(last_fd); } + +void file_cache_dump(FileCacheData *fc) +{ + GList *work; + work = fc->list; + + while(work) + { + FileData *fd = work->data; + work = work->next; + DEBUG_1("cache entry: %s", fd->path); + } +}
--- a/src/filecache.h Sat Jun 21 11:05:55 2008 +0000 +++ b/src/filecache.h Sat Jun 21 16:00:13 2008 +0000 @@ -22,5 +22,6 @@ FileCacheData *file_cache_new(FileCacheReleaseFunc release, gulong max_size); gint file_cache_get(FileCacheData *fc, FileData *fd); void file_cache_put(FileCacheData *fc, FileData *fd, gulong size); +void file_cache_dump(FileCacheData *fc); #endif
--- a/src/filedata.c Sat Jun 21 11:05:55 2008 +0000 +++ b/src/filedata.c Sat Jun 21 16:00:13 2008 +0000 @@ -447,6 +447,7 @@ FileData *file_data_ref(FileData *fd) { if (fd == NULL) return NULL; + DEBUG_2("file_data_ref (%d): '%s'", fd->ref, fd->path); // return g_memdup(fd, sizeof(FileData)); g_assert(fd->magick == 0x12345678);
--- a/src/image.c Sat Jun 21 11:05:55 2008 +0000 +++ b/src/image.c Sat Jun 21 16:00:13 2008 +0000 @@ -28,6 +28,7 @@ #include "ui_fileops.h" #include "filedata.h" +#include "filecache.h" #include <math.h> @@ -51,8 +52,8 @@ static void image_update_title(ImageWindow *imd); -static void image_post_process(ImageWindow *imd, gint clamp); static void image_read_ahead_start(ImageWindow *imd); +static void image_cache_set(ImageWindow *imd, FileData *fd); /* *------------------------------------------------------------------- @@ -206,130 +207,6 @@ *------------------------------------------------------------------- */ - -#if 0 - -static void image_alter_real(ImageWindow *imd, AlterType type, gint clamp) -{ - PixbufRenderer *pr; - GdkPixbuf *new = NULL; - gint exif_rotate; - gint x, y; - gint t; - - pr = (PixbufRenderer *)imd->pr; - - exif_rotate = (imd->delay_alter_type != ALTER_NONE && (imd->state & IMAGE_STATE_ROTATE_AUTO)); - imd->delay_alter_type = ALTER_NONE; - - if (!pr->pixbuf) return; - - x = pr->x_scroll + (pr->vis_width / 2); - y = pr->y_scroll + (pr->vis_height / 2); - - switch (type) - { - case ALTER_ROTATE_90: - new = pixbuf_copy_rotate_90(pr->pixbuf, FALSE); - t = x; - x = pr->height - y; - y = t; - break; - case ALTER_ROTATE_90_CC: - new = pixbuf_copy_rotate_90(pr->pixbuf, TRUE); - t = x; - x = y; - y = pr->width - t; - break; - case ALTER_ROTATE_180: - new = pixbuf_copy_mirror(pr->pixbuf, TRUE, TRUE); - x = pr->width - x; - y = pr->height - y; - break; - case ALTER_MIRROR: - new = pixbuf_copy_mirror(pr->pixbuf, TRUE, FALSE); - x = pr->width - x; - break; - case ALTER_FLIP: - new = pixbuf_copy_mirror(pr->pixbuf, FALSE, TRUE); - y = pr->height - y; - break; - case ALTER_DESATURATE: - pixbuf_desaturate_rect(pr->pixbuf, - 0, 0, pr->image_width, pr->image_height); - image_area_changed(imd, 0, 0, pr->image_width, pr->image_height); - layout_image_overlay_update(layout_find_by_image(imd)); - break; - case ALTER_NONE: - default: - return; - break; - } - - if (!new) return; - - pixbuf_renderer_set_pixbuf(pr, new, pr->zoom); - g_object_unref(new); - - if (clamp && pr->zoom != 0.0 && pr->scale != 0.0) - { - if (exif_rotate) - { - switch (pr->scroll_reset) - { - case PR_SCROLL_RESET_NOCHANGE: - break; - case PR_SCROLL_RESET_CENTER: - x = (gint)((gdouble)pr->image_width / 2.0 * pr->scale); - y = (gint)((gdouble)pr->image_height / 2.0 * pr->scale); - break; - case PR_SCROLL_RESET_TOPLEFT: - default: - x = 0; - y = 0; - break; - } - } - pixbuf_renderer_scroll_to_point(pr, (gint)((gdouble)x / pr->scale), - (gint)((gdouble)y / pr->scale), - 0.50, 0.50); - } - - if (exif_rotate) image_state_set(imd, IMAGE_STATE_ROTATE_AUTO); - layout_image_overlay_update(layout_find_by_image(imd)); - DEBUG_1("%s image postprocess done: %s", get_exec_time(), imd->image_fd->name); -} - -static void image_post_process_alter(ImageWindow *imd, gint clamp) -{ - if (imd->delay_alter_type != ALTER_NONE) - { - image_alter_real(imd, imd->delay_alter_type, clamp); - } -} - - -static void image_post_process_color_cb(ColorMan *cm, ColorManReturnType type, gpointer data) -{ - ImageWindow *imd = data; - - color_man_free(cm); - if (type == COLOR_RETURN_IMAGE_CHANGED) - { - if (cm == imd->cm) imd->cm = NULL; - return; - } - - imd->cm = NULL; - image_state_set(imd, IMAGE_STATE_COLOR_ADJ); - DEBUG_1("%s image postprocess cm done: %s", get_exec_time(), imd->image_fd->name); - - image_post_process_alter(imd, FALSE); - - image_read_ahead_start(imd); -} -#endif - static gint image_post_process_color(ImageWindow *imd, gint start_row, ExifData *exif, gint run_in_bg) { ColorMan *cm; @@ -449,95 +326,6 @@ return FALSE; } -static void image_post_process(ImageWindow *imd, gint clamp) -{ -#if 0 - ExifData *exif = NULL; - - if (!image_get_pixbuf(imd)) return; - - DEBUG_1("%s image postprocess: %s", get_exec_time(), imd->image_fd->name); - - if (options->image.exif_rotate_enable || - (imd->color_profile_enable && imd->color_profile_use_image) ) - { - exif = exif_read_fd(imd->image_fd); - } - if (options->image.exif_rotate_enable && exif) - { - gint orientation; - - if (exif_get_integer(exif, "Exif.Image.Orientation", &orientation)) - { - gint rotate = TRUE; - - /* see http://jpegclub.org/exif_orientation.html - 1 2 3 4 5 6 7 8 - - 888888 888888 88 88 8888888888 88 88 8888888888 - 88 88 88 88 88 88 88 88 88 88 88 88 - 8888 8888 8888 8888 88 8888888888 8888888888 88 - 88 88 88 88 - 88 88 888888 888888 - */ - switch (orientation) - { - case EXIF_ORIENTATION_TOP_LEFT: - /* normal -- nothing to do */ - rotate = FALSE; - break; - case EXIF_ORIENTATION_TOP_RIGHT: - /* mirrored */ - imd->delay_alter_type = ALTER_MIRROR; - break; - case EXIF_ORIENTATION_BOTTOM_RIGHT: - /* upside down */ - imd->delay_alter_type = ALTER_ROTATE_180; - break; - case EXIF_ORIENTATION_BOTTOM_LEFT: - /* flipped */ - imd->delay_alter_type = ALTER_FLIP; - break; - case EXIF_ORIENTATION_LEFT_TOP: - /* not implemented -- too wacky to fix in one step */ - rotate = FALSE; - break; - case EXIF_ORIENTATION_RIGHT_TOP: - /* rotated -90 (270) */ - imd->delay_alter_type = ALTER_ROTATE_90; - break; - case EXIF_ORIENTATION_RIGHT_BOTTOM: - /* not implemented -- too wacky to fix in one step */ - rotate = FALSE; - break; - case EXIF_ORIENTATION_LEFT_BOTTOM: - /* rotated 90 */ - imd->delay_alter_type = ALTER_ROTATE_90_CC; - break; - default: - /* The other values are out of range */ - rotate = FALSE; - break; - } - - if (rotate) image_state_set(imd, IMAGE_STATE_ROTATE_AUTO); - } - } - if (imd->color_profile_enable) - { - if (!image_post_process_color(imd, 0, exif, TRUE)) - { - /* fixme: note error to user */ - image_state_set(imd, IMAGE_STATE_COLOR_ADJ); - } - } - - - if (!imd->cm) image_post_process_alter(imd, clamp); - - exif_free_fd(fd, exif); -#endif -} static void image_post_process_tile_color_cb(PixbufRenderer *pr, GdkPixbuf **pixbuf, gint x, gint y, gint w, gint h, gpointer data) { @@ -621,9 +409,6 @@ image_loader_free(imd->read_ahead_il); imd->read_ahead_il = NULL; - if (imd->read_ahead_pixbuf) g_object_unref(imd->read_ahead_pixbuf); - imd->read_ahead_pixbuf = NULL; - file_data_unref(imd->read_ahead_fd); imd->read_ahead_fd = NULL; } @@ -634,14 +419,18 @@ DEBUG_1("%s read ahead done for :%s", get_exec_time(), imd->read_ahead_fd->path); - imd->read_ahead_pixbuf = image_loader_get_pixbuf(imd->read_ahead_il); - if (imd->read_ahead_pixbuf) + if (!imd->read_ahead_fd->pixbuf) { - g_object_ref(imd->read_ahead_pixbuf); - } - else - { - imd->read_ahead_pixbuf = pixbuf_inline(PIXBUF_INLINE_BROKEN); + imd->read_ahead_fd->pixbuf = image_loader_get_pixbuf(imd->read_ahead_il); + if (imd->read_ahead_fd->pixbuf) + { + g_object_ref(imd->read_ahead_fd->pixbuf); + image_cache_set(imd, imd->read_ahead_fd); + } + else + { + imd->read_ahead_fd->pixbuf = pixbuf_inline(PIXBUF_INLINE_BROKEN); + } } image_loader_free(imd->read_ahead_il); imd->read_ahead_il = NULL; @@ -658,7 +447,7 @@ static void image_read_ahead_start(ImageWindow *imd) { /* already started ? */ - if (!imd->read_ahead_fd || imd->read_ahead_il || imd->read_ahead_pixbuf) return; + if (!imd->read_ahead_fd || imd->read_ahead_il || imd->read_ahead_fd->pixbuf) return; /* still loading ?, do later */ if (imd->il /*|| imd->cm*/) return; @@ -694,58 +483,39 @@ *------------------------------------------------------------------- */ -static void image_post_buffer_set(ImageWindow *imd, FileData *fd, GdkPixbuf *pixbuf, gint color_row) +static void image_cache_release_cb(FileData *fd) { - file_data_unref(imd->prev_fd); - if (imd->prev_pixbuf) g_object_unref(imd->prev_pixbuf); - - if (fd && pixbuf) - { - imd->prev_fd = file_data_ref(fd); - - g_object_ref(pixbuf); - imd->prev_pixbuf = pixbuf; - imd->prev_color_row = color_row; - } - else - { - imd->prev_fd = NULL; - imd->prev_pixbuf = NULL; - imd->prev_color_row = -1; - } - - DEBUG_1("%s post buffer set: %s", get_exec_time(), fd ? fd->path : "null"); + g_object_unref(fd->pixbuf); + fd->pixbuf = NULL; } -static gint image_post_buffer_get(ImageWindow *imd) +static FileCacheData *image_get_cache() +{ + static FileCacheData *cache = NULL; + if (!cache) cache = file_cache_new(image_cache_release_cb, 5); + return cache; +} + +static void image_cache_set(ImageWindow *imd, FileData *fd) +{ + + file_cache_put(image_get_cache(), fd, 1); + + g_assert(fd->pixbuf); +} + +static gint image_cache_get(ImageWindow *imd) { gint success; - if (imd->prev_pixbuf && - imd->image_fd && imd->prev_fd && imd->image_fd == imd->prev_fd) + success = file_cache_get(image_get_cache(), imd->image_fd); + if (success) { - image_change_pixbuf(imd, imd->prev_pixbuf, image_zoom_get(imd)); - if (imd->prev_color_row >= 0) - { - ExifData *exif = NULL; - - if (imd->color_profile_use_image) exif = exif_read_fd(imd->image_fd); -// image_post_process_color(imd, imd->prev_color_row, exif, TRUE); - exif_free_fd(imd->image_fd, exif); - } - success = TRUE; + g_assert(imd->image_fd->pixbuf); + image_change_pixbuf(imd, imd->image_fd->pixbuf, image_zoom_get(imd)); } - else - { - success = FALSE; - } - - if (imd->prev_pixbuf) g_object_unref(imd->prev_pixbuf); - imd->prev_pixbuf = NULL; - - file_data_unref(imd->prev_fd); - imd->prev_fd = NULL; - + + file_cache_dump(image_get_cache()); return success; } @@ -789,6 +559,12 @@ g_object_set(G_OBJECT(imd->pr), "loading", FALSE, NULL); image_state_unset(imd, IMAGE_STATE_LOADING); + if (options->image.enable_read_ahead && imd->image_fd && !imd->image_fd->pixbuf && image_loader_get_pixbuf(imd->il)) + { + imd->image_fd->pixbuf = gdk_pixbuf_ref(image_loader_get_pixbuf(imd->il)); + image_cache_set(imd, imd->image_fd); + } + if (imd->delay_flip && image_get_pixbuf(imd) != image_loader_get_pixbuf(imd->il)) { @@ -799,7 +575,7 @@ image_loader_free(imd->il); imd->il = NULL; - image_post_process(imd, TRUE); +// image_post_process(imd, TRUE); image_read_ahead_start(imd); } @@ -866,18 +642,18 @@ image_change_pixbuf(imd, image_loader_get_pixbuf(imd->il), image_zoom_get(imd)); } - image_read_ahead_cancel(imd); + file_data_unref(imd->read_ahead_fd); + imd->read_ahead_fd = NULL; return TRUE; } - else if (imd->read_ahead_pixbuf) + else if (imd->read_ahead_fd->pixbuf) { - image_change_pixbuf(imd, imd->read_ahead_pixbuf, image_zoom_get(imd)); - g_object_unref(imd->read_ahead_pixbuf); - imd->read_ahead_pixbuf = NULL; + image_change_pixbuf(imd, imd->read_ahead_fd->pixbuf, image_zoom_get(imd)); - image_read_ahead_cancel(imd); + file_data_unref(imd->read_ahead_fd); + imd->read_ahead_fd = NULL; - image_post_process(imd, FALSE); +// image_post_process(imd, FALSE); return TRUE; } @@ -894,7 +670,7 @@ imd->completed = FALSE; g_object_set(G_OBJECT(imd->pr), "complete", FALSE, NULL); - if (image_post_buffer_get(imd)) + if (image_cache_get(imd)) { DEBUG_1("from post buffer: %s", imd->image_fd->path); return TRUE; @@ -1027,56 +803,15 @@ static void image_change_real(ImageWindow *imd, FileData *fd, CollectionData *cd, CollectInfo *info, gdouble zoom) { - GdkPixbuf *pixbuf; - GdkPixbuf *prev_pixbuf = NULL; - FileData *prev_fd = NULL; - gint prev_clear = FALSE; - gint prev_color_row = -1; imd->collection = cd; imd->collection_info = info; - pixbuf = image_get_pixbuf(imd); - - if (options->image.enable_read_ahead && imd->image_fd && pixbuf) - { - if (imd->il) - { - /* current image is not finished */ - prev_clear = TRUE; - } - else - { - prev_fd = file_data_ref(imd->image_fd); - prev_pixbuf = pixbuf; - g_object_ref(prev_pixbuf); - - if (imd->cm) - { - ColorMan *cm; - - cm = (ColorMan *)imd->cm; - prev_color_row = cm->row; - } - } - } - file_data_unref(imd->image_fd); imd->image_fd = file_data_ref(fd); image_change_complete(imd, zoom, TRUE); - if (prev_pixbuf) - { - image_post_buffer_set(imd, prev_fd, prev_pixbuf, prev_color_row); - file_data_unref(prev_fd); - g_object_unref(prev_pixbuf); - } - else if (prev_clear) - { - image_post_buffer_set(imd, NULL, NULL, -1); - } - image_update_title(imd); image_state_set(imd, IMAGE_STATE_IMAGE); } @@ -1386,15 +1121,16 @@ imd->size = source->size; imd->mtime = source->mtime; - image_set_fd(imd, image_get_fd(source)); - image_loader_free(imd->il); imd->il = NULL; + image_set_fd(imd, image_get_fd(source)); + + if (source->il) { - imd->il = source->il; - source->il = NULL; +// imd->il = source->il; +// source->il = NULL; image_loader_sync_data(imd->il, imd); @@ -1425,24 +1161,10 @@ source->read_ahead_il = NULL; if (imd->read_ahead_il) image_loader_sync_data(imd->read_ahead_il, imd); - if (imd->read_ahead_pixbuf) g_object_unref(imd->read_ahead_pixbuf); - imd->read_ahead_pixbuf = source->read_ahead_pixbuf; - source->read_ahead_pixbuf = NULL; - file_data_unref(imd->read_ahead_fd); imd->read_ahead_fd = source->read_ahead_fd; source->read_ahead_fd = NULL; - if (imd->prev_pixbuf) g_object_unref(imd->prev_pixbuf); - imd->prev_pixbuf = source->prev_pixbuf; - source->prev_pixbuf = NULL; - imd->prev_color_row = source->prev_color_row; - source->prev_color_row = -1; - - file_data_unref(imd->prev_fd); - imd->prev_fd = source->prev_fd; - source->prev_fd = NULL; - imd->completed = source->completed; imd->state = source->state; source->state = IMAGE_STATE_NONE; @@ -1494,29 +1216,6 @@ pixbuf_renderer_set_scroll_center(PIXBUF_RENDERER(imd->pr), x, y); } - -#if 0 -void image_alter(ImageWindow *imd, AlterType type) -{ - if (pixbuf_renderer_get_tiles((PixbufRenderer *)imd->pr)) return; - - if (imd->il || imd->cm) - { - /* still loading, wait till done */ - imd->delay_alter_type = type; - image_state_set(imd, IMAGE_STATE_ROTATE_USER); - - if (imd->cm && (imd->state & IMAGE_STATE_ROTATE_AUTO)) - { - image_state_unset(imd, IMAGE_STATE_ROTATE_AUTO); - } - return; - } - - image_alter_real(imd, type, TRUE); -} -#endif - void image_zoom_adjust(ImageWindow *imd, gdouble increment) { pixbuf_renderer_zoom_adjust((PixbufRenderer *)imd->pr, increment); @@ -1650,7 +1349,10 @@ if (fd) { - image_read_ahead_set(imd, fd); + if (!file_cache_get(image_get_cache(), fd)) + { + image_read_ahead_set(imd, fd); + } } else { @@ -1911,7 +1613,6 @@ image_reset(imd); image_read_ahead_cancel(imd); - image_post_buffer_set(imd, NULL, NULL, -1); image_auto_refresh(imd, -1); file_data_unref(imd->image_fd); @@ -2011,7 +1712,6 @@ imd->delay_alter_type = ALTER_NONE; imd->read_ahead_il = NULL; - imd->read_ahead_pixbuf = NULL; imd->read_ahead_fd = NULL; imd->completed = FALSE;
--- a/src/typedefs.h Sat Jun 21 11:05:55 2008 +0000 +++ b/src/typedefs.h Sat Jun 21 16:00:13 2008 +0000 @@ -349,7 +349,8 @@ time_t mtime; /* file modified time stamp */ gint unknown; /* failed to load image */ - ImageLoader *il; + ImageLoader *il; /* FIXME - image loader should probably go to FileData, but it must first support + sending callbacks to multiple ImageWindows in parallel */ gint has_frame; @@ -405,12 +406,9 @@ AlterType delay_alter_type; + FileData *read_ahead_fd; ImageLoader *read_ahead_il; - GdkPixbuf *read_ahead_pixbuf; - FileData *read_ahead_fd; - GdkPixbuf *prev_pixbuf; - FileData *prev_fd; gint prev_color_row; gint auto_refresh_id; @@ -447,6 +445,9 @@ FileData *parent; /* parent file if this is a sidecar file, NULL otherwise */ FileDataChangeInfo *change; /* for rename, move ... */ GdkPixbuf *thumb_pixbuf; + + GdkPixbuf *pixbuf; /* full-size image */ + gint ref; gint version; /* increased when any field in this structure is changed */ gint user_orientation;