Revision: 1140
http://geeqie.svn.sourceforge.net/geeqie/?rev=1140&view=rev
Author: nadvornik
Date: 2008-09-08 19:57:51 +0000 (Mon, 08 Sep 2008)
Log Message:
-----------
added possibility to redraw only the parts of image that are already
loaded
Modified Paths:
--------------
trunk/src/image-load.c
trunk/src/image-load.h
trunk/src/image.c
trunk/src/image.h
trunk/src/layout.c
trunk/src/pixbuf-renderer.c
trunk/src/pixbuf-renderer.h
trunk/src/print.c
Modified: trunk/src/image-load.c
===================================================================
--- trunk/src/image-load.c 2008-09-08 15:53:01 UTC (rev 1139)
+++ trunk/src/image-load.c 2008-09-08 19:57:51 UTC (rev 1140)
@@ -172,6 +172,12 @@
il->area_param_list = g_list_delete_link(il->area_param_list,
il->area_param_list);
}
+ while (il->area_param_delayed_list)
+ {
+ g_free(il->area_param_delayed_list->data);
+ il->area_param_delayed_list =
g_list_delete_link(il->area_param_delayed_list, il->area_param_delayed_list);
+ }
+
if (il->pixbuf) g_object_unref(il->pixbuf);
file_data_unref(il->fd);
@@ -267,6 +273,7 @@
g_idle_add_full(G_PRIORITY_HIGH, image_loader_emit_percent_cb, il,
NULL);
}
+/* this function expects that il->data_mutex is locked by caller */
static void image_loader_emit_area_ready(ImageLoader *il, guint x, guint y,
guint w, guint h)
{
ImageLoaderAreaParam *par = g_new0(ImageLoaderAreaParam, 1);
@@ -276,9 +283,7 @@
par->w = w;
par->h = h;
- g_mutex_lock(il->data_mutex);
il->area_param_list = g_list_prepend(il->area_param_list, par);
- g_mutex_unlock(il->data_mutex);
g_idle_add_full(G_PRIORITY_HIGH, image_loader_emit_area_ready_cb, par,
NULL);
}
@@ -286,6 +291,21 @@
/**************************************************************************************/
/* the following functions may be executed in separate thread */
+/* this function expects that il->data_mutex is locked by caller */
+static void image_loader_queue_delayed_erea_ready(ImageLoader *il, guint x,
guint y, guint w, guint h)
+{
+ ImageLoaderAreaParam *par = g_new0(ImageLoaderAreaParam, 1);
+ par->il = il;
+ par->x = x;
+ par->y = y;
+ par->w = w;
+ par->h = h;
+
+ il->area_param_delayed_list =
g_list_prepend(il->area_param_delayed_list, par);
+}
+
+
+
static gint image_loader_get_stopping(ImageLoader *il)
{
gint ret;
@@ -298,6 +318,7 @@
return ret;
}
+
static void image_loader_sync_pixbuf(ImageLoader *il)
{
GdkPixbuf *pb;
@@ -340,7 +361,13 @@
log_printf("critical: area_ready signal with NULL
pixbuf (out of mem?)\n");
}
}
- image_loader_emit_area_ready(il, x, y, w, h);
+
+ g_mutex_lock(il->data_mutex);
+ if (il->delay_area_ready)
+ image_loader_queue_delayed_erea_ready(il, x, y, w, h);
+ else
+ image_loader_emit_area_ready(il, x, y, w, h);
+ g_mutex_unlock(il->data_mutex);
}
static void image_loader_area_prepared_cb(GdkPixbufLoader *loader, gpointer
data)
@@ -666,6 +693,38 @@
}
+void image_loader_delay_area_ready(ImageLoader *il, gint enable)
+{
+ g_mutex_lock(il->data_mutex);
+ il->delay_area_ready = enable;
+ if (!enable)
+ {
+ /* send delayed */
+ GList *list, *work;
+ list = g_list_reverse(il->area_param_delayed_list);
+ il->area_param_delayed_list = NULL;
+ g_mutex_unlock(il->data_mutex);
+
+ work = list;
+
+ while (work)
+ {
+ ImageLoaderAreaParam *par = work->data;
+ work = work->next;
+
+ g_signal_emit(il, signals[SIGNAL_AREA_READY], 0,
par->x, par->y, par->w, par->h);
+ g_free(par);
+ }
+ g_list_free(list);
+ }
+ else
+ {
+ /* just unlock */
+ g_mutex_unlock(il->data_mutex);
+ }
+}
+
+
/**************************************************************************************/
/* execution via idle calls */
Modified: trunk/src/image-load.h
===================================================================
--- trunk/src/image-load.h 2008-09-08 15:53:01 UTC (rev 1139)
+++ trunk/src/image-load.h 2008-09-08 19:57:51 UTC (rev 1140)
@@ -45,7 +45,10 @@
gint idle_done_id;
GList *area_param_list;
+ GList *area_param_delayed_list;
+ gint delay_area_ready;
+
GMutex *data_mutex;
gint stopping;
gint can_destroy;
@@ -73,6 +76,8 @@
void image_loader_free(ImageLoader *il);
+/* delay area_ready signals */
+void image_loader_delay_area_ready(ImageLoader *il, gint enable);
/* Speed up loading when you only need at most width x height size image,
* only the jpeg GdkPixbuf loader benefits from it - so there is no
Modified: trunk/src/image.c
===================================================================
--- trunk/src/image.c 2008-09-08 15:53:01 UTC (rev 1139)
+++ trunk/src/image.c 2008-09-08 19:57:51 UTC (rev 1140)
@@ -432,6 +432,8 @@
DEBUG_1("%s read ahead started for :%s", get_exec_time(),
imd->read_ahead_fd->path);
imd->read_ahead_il = image_loader_new(imd->read_ahead_fd);
+
+ image_loader_delay_area_ready(imd->read_ahead_il, TRUE); /* we will
need the area_ready signals later */
g_signal_connect (G_OBJECT(imd->read_ahead_il), "error",
(GCallback)image_read_ahead_error_cb, imd);
g_signal_connect (G_OBJECT(imd->read_ahead_il), "done",
(GCallback)image_read_ahead_done_cb, imd);
@@ -491,7 +493,7 @@
if (success)
{
g_assert(imd->image_fd->pixbuf);
- image_change_pixbuf(imd, imd->image_fd->pixbuf,
image_zoom_get(imd));
+ image_change_pixbuf(imd, imd->image_fd->pixbuf,
image_zoom_get(imd), FALSE);
}
file_cache_dump(image_get_cache());
@@ -508,7 +510,7 @@
{
if (image_get_pixbuf(imd) || !imd->il) return;
- image_change_pixbuf(imd, image_loader_get_pixbuf(imd->il),
image_zoom_get(imd));
+ image_change_pixbuf(imd, image_loader_get_pixbuf(imd->il),
image_zoom_get(imd), FALSE);
}
static void image_load_area_cb(ImageLoader *il, guint x, guint y, guint w,
guint h, gpointer data)
@@ -524,7 +526,7 @@
return;
}
- if (!pr->pixbuf) image_load_pixbuf_ready(imd);
+ if (!pr->pixbuf) image_change_pixbuf(imd,
image_loader_get_pixbuf(imd->il), image_zoom_get(imd), TRUE);
pixbuf_renderer_area_changed(pr, x, y, w, h);
}
@@ -549,7 +551,7 @@
GdkPixbuf *pixbuf;
pixbuf = pixbuf_inline(PIXBUF_INLINE_BROKEN);
- image_change_pixbuf(imd, pixbuf, image_zoom_get(imd));
+ image_change_pixbuf(imd, pixbuf, image_zoom_get(imd), FALSE);
g_object_unref(pixbuf);
imd->unknown = TRUE;
@@ -558,7 +560,7 @@
image_get_pixbuf(imd) != image_loader_get_pixbuf(imd->il))
{
g_object_set(G_OBJECT(imd->pr), "complete", FALSE, NULL);
- image_change_pixbuf(imd, image_loader_get_pixbuf(imd->il),
image_zoom_get(imd));
+ image_change_pixbuf(imd, image_loader_get_pixbuf(imd->il),
image_zoom_get(imd), FALSE);
}
image_loader_free(imd->il);
@@ -608,16 +610,18 @@
if (!imd->delay_flip)
{
- image_change_pixbuf(imd,
image_loader_get_pixbuf(imd->il), image_zoom_get(imd));
+ image_change_pixbuf(imd,
image_loader_get_pixbuf(imd->il), image_zoom_get(imd), TRUE);
}
+ image_loader_delay_area_ready(imd->il, FALSE); /* send the
delayed area_ready signals */
+
file_data_unref(imd->read_ahead_fd);
imd->read_ahead_fd = NULL;
return TRUE;
}
else if (imd->read_ahead_fd->pixbuf)
{
- image_change_pixbuf(imd, imd->read_ahead_fd->pixbuf,
image_zoom_get(imd));
+ image_change_pixbuf(imd, imd->read_ahead_fd->pixbuf,
image_zoom_get(imd), FALSE);
file_data_unref(imd->read_ahead_fd);
imd->read_ahead_fd = NULL;
@@ -684,8 +688,12 @@
image_state_set(imd, IMAGE_STATE_LOADING);
- if (!imd->delay_flip && !image_get_pixbuf(imd))
image_load_pixbuf_ready(imd);
-
+/*
+ if (!imd->delay_flip && !image_get_pixbuf(imd) &&
image_loader_get_pixbuf(imd->il))
+ {
+ image_change_pixbuf(imd, image_loader_get_pixbuf(imd->il),
image_zoom_get(imd), TRUE);
+ }
+*/
return TRUE;
}
@@ -734,7 +742,7 @@
GdkPixbuf *pixbuf;
pixbuf = pixbuf_inline(PIXBUF_INLINE_BROKEN);
- image_change_pixbuf(imd, pixbuf, zoom);
+ image_change_pixbuf(imd, pixbuf, zoom, FALSE);
g_object_unref(pixbuf);
imd->unknown = TRUE;
@@ -747,12 +755,12 @@
GdkPixbuf *pixbuf;
pixbuf = pixbuf_inline(PIXBUF_INLINE_BROKEN);
- image_change_pixbuf(imd, pixbuf, zoom);
+ image_change_pixbuf(imd, pixbuf, zoom, FALSE);
g_object_unref(pixbuf);
}
else
{
- image_change_pixbuf(imd, NULL, zoom);
+ image_change_pixbuf(imd, NULL, zoom, FALSE);
}
imd->unknown = TRUE;
}
@@ -988,7 +996,7 @@
return pixbuf_renderer_get_pixbuf((PixbufRenderer *)imd->pr);
}
-void image_change_pixbuf(ImageWindow *imd, GdkPixbuf *pixbuf, gdouble zoom)
+void image_change_pixbuf(ImageWindow *imd, GdkPixbuf *pixbuf, gdouble zoom,
gint lazy)
{
ExifData *exif = NULL;
@@ -1023,8 +1031,15 @@
imd->cm = NULL;
}
- pixbuf_renderer_set_pixbuf((PixbufRenderer *)imd->pr, pixbuf, zoom);
- pixbuf_renderer_set_orientation((PixbufRenderer *)imd->pr,
imd->orientation);
+ if (lazy)
+ {
+ pixbuf_renderer_set_pixbuf_lazy((PixbufRenderer *)imd->pr,
pixbuf, zoom, imd->orientation);
+ }
+ else
+ {
+ pixbuf_renderer_set_pixbuf((PixbufRenderer *)imd->pr, pixbuf,
zoom);
+ pixbuf_renderer_set_orientation((PixbufRenderer *)imd->pr,
imd->orientation);
+ }
if (imd->color_profile_enable)
{
Modified: trunk/src/image.h
===================================================================
--- trunk/src/image.h 2008-09-08 15:53:01 UTC (rev 1139)
+++ trunk/src/image.h 2008-09-08 19:57:51 UTC (rev 1140)
@@ -56,7 +56,7 @@
/* load a new image */
void image_change_fd(ImageWindow *imd, FileData *fd, gdouble zoom);
-void image_change_pixbuf(ImageWindow *imd, GdkPixbuf *pixbuf, gdouble zoom);
+void image_change_pixbuf(ImageWindow *imd, GdkPixbuf *pixbuf, gdouble zoom,
gint lazy);
void image_change_from_collection(ImageWindow *imd, CollectionData *cd,
CollectInfo *info, gdouble zoom);
CollectionData *image_get_collection(ImageWindow *imd, CollectInfo **info);
void image_change_from_image(ImageWindow *imd, ImageWindow *source);
Modified: trunk/src/layout.c
===================================================================
--- trunk/src/layout.c 2008-09-08 15:53:01 UTC (rev 1139)
+++ trunk/src/layout.c 2008-09-08 19:57:51 UTC (rev 1140)
@@ -1988,7 +1988,7 @@
GdkPixbuf *pixbuf;
pixbuf = pixbuf_inline(PIXBUF_INLINE_LOGO);
- image_change_pixbuf(lw->image, pixbuf, 1.0);
+ image_change_pixbuf(lw->image, pixbuf, 1.0, FALSE);
g_object_unref(pixbuf);
}
Modified: trunk/src/pixbuf-renderer.c
===================================================================
--- trunk/src/pixbuf-renderer.c 2008-09-08 15:53:01 UTC (rev 1139)
+++ trunk/src/pixbuf-renderer.c 2008-09-08 19:57:51 UTC (rev 1140)
@@ -181,6 +181,7 @@
PR_ZOOM_NEW = 1 << 1,
PR_ZOOM_CENTER = 1 << 2,
PR_ZOOM_INVALIDATE = 1 << 3,
+ PR_ZOOM_LAZY = 1 << 4 /* wait with redraw for
pixbuf_renderer_area_changed */
} PrZoomFlags;
static guint signals[SIGNAL_COUNT] = { 0 };
@@ -3192,6 +3193,7 @@
gboolean force = !!(flags & PR_ZOOM_FORCE);
gboolean new = !!(flags & PR_ZOOM_NEW);
gboolean invalidate = !!(flags & PR_ZOOM_INVALIDATE);
+ gboolean lazy = !!(flags & PR_ZOOM_LAZY);
zoom = CLAMP(zoom, pr->zoom_min, pr->zoom_max);
@@ -3285,7 +3287,7 @@
if (invalidate || invalid)
{
pr_tile_invalidate_all(pr);
- pr_redraw(pr, TRUE);
+ if (!lazy) pr_redraw(pr, TRUE);
}
if (redrawn) *redrawn = (invalidate || invalid);
@@ -3305,6 +3307,7 @@
gboolean center_point = !!(flags & PR_ZOOM_CENTER);
gboolean force = !!(flags & PR_ZOOM_FORCE);
gboolean new = !!(flags & PR_ZOOM_NEW);
+ gboolean lazy = !!(flags & PR_ZOOM_LAZY);
PrZoomFlags clamp_flags = flags;
gdouble old_center_x = pr->norm_center_x;
gdouble old_center_y = pr->norm_center_y;
@@ -3325,6 +3328,7 @@
}
if (force) clamp_flags |= PR_ZOOM_INVALIDATE;
+ if (lazy) clamp_flags |= PR_ZOOM_LAZY;
if (!pr_zoom_clamp(pr, zoom, clamp_flags, &redrawn)) return;
clamped = pr_size_clamp(pr);
@@ -3374,7 +3378,15 @@
* so redraw the window anyway :/
*/
if (sized || clamped) pr_border_clear(pr);
- pr_redraw(pr, redrawn);
+
+ if (lazy)
+ {
+ pr_queue_clear(pr);
+ }
+ else
+ {
+ pr_redraw(pr, redrawn);
+ }
pr_scroll_notify_signal(pr);
pr_zoom_signal(pr);
@@ -3820,8 +3832,12 @@
}
}
-static void pr_pixbuf_sync(PixbufRenderer *pr, gdouble zoom)
+static void pr_set_pixbuf(PixbufRenderer *pr, GdkPixbuf *pixbuf, gdouble zoom,
PrZoomFlags flags)
{
+ if (pixbuf) g_object_ref(pixbuf);
+ if (pr->pixbuf) g_object_unref(pr->pixbuf);
+ pr->pixbuf = pixbuf;
+
if (!pr->pixbuf)
{
GtkWidget *box;
@@ -3845,25 +3861,28 @@
}
pr_pixbuf_size_sync(pr);
- pr_zoom_sync(pr, zoom, PR_ZOOM_FORCE | PR_ZOOM_NEW, 0, 0);
+ pr_zoom_sync(pr, zoom, flags | PR_ZOOM_FORCE | PR_ZOOM_NEW, 0, 0);
}
-static void pr_set_pixbuf(PixbufRenderer *pr, GdkPixbuf *pixbuf, gdouble zoom)
+void pixbuf_renderer_set_pixbuf(PixbufRenderer *pr, GdkPixbuf *pixbuf, gdouble
zoom)
{
- if (pixbuf) g_object_ref(pixbuf);
- if (pr->pixbuf) g_object_unref(pr->pixbuf);
- pr->pixbuf = pixbuf;
+ g_return_if_fail(IS_PIXBUF_RENDERER(pr));
- pr_pixbuf_sync(pr, zoom);
+ pr_source_tile_unset(pr);
+
+ pr_set_pixbuf(pr, pixbuf, zoom, 0);
+
+ pr_update_signal(pr);
}
-void pixbuf_renderer_set_pixbuf(PixbufRenderer *pr, GdkPixbuf *pixbuf, gdouble
zoom)
+void pixbuf_renderer_set_pixbuf_lazy(PixbufRenderer *pr, GdkPixbuf *pixbuf,
gdouble zoom, gint orientation)
{
g_return_if_fail(IS_PIXBUF_RENDERER(pr));
pr_source_tile_unset(pr);
- pr_set_pixbuf(pr, pixbuf, zoom);
+ pr->orientation = orientation;
+ pr_set_pixbuf(pr, pixbuf, zoom, PR_ZOOM_LAZY);
pr_update_signal(pr);
}
Modified: trunk/src/pixbuf-renderer.h
===================================================================
--- trunk/src/pixbuf-renderer.h 2008-09-08 15:53:01 UTC (rev 1139)
+++ trunk/src/pixbuf-renderer.h 2008-09-08 19:57:51 UTC (rev 1140)
@@ -179,6 +179,11 @@
/* display a pixbuf */
void pixbuf_renderer_set_pixbuf(PixbufRenderer *pr, GdkPixbuf *pixbuf, gdouble
zoom);
+
+/* same as pixbuf_renderer_set_pixbuf but waits with redrawing for
pixbuf_renderer_area_changed */
+void pixbuf_renderer_set_pixbuf_lazy(PixbufRenderer *pr, GdkPixbuf *pixbuf,
gdouble zoom, gint orientation);
+
+
GdkPixbuf *pixbuf_renderer_get_pixbuf(PixbufRenderer *pr);
void pixbuf_renderer_set_orientation(PixbufRenderer *pr, gint orientation);
Modified: trunk/src/print.c
===================================================================
--- trunk/src/print.c 2008-09-08 15:53:01 UTC (rev 1139)
+++ trunk/src/print.c 2008-09-08 19:57:51 UTC (rev 1140)
@@ -627,7 +627,7 @@
gdk_pixbuf_get_height(pixbuf) != sh)
{
pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, sw, sh);
- image_change_pixbuf(pw->layout_image, pixbuf, 0.0);
+ image_change_pixbuf(pw->layout_image, pixbuf, 0.0, FALSE);
g_object_unref(pixbuf);
}
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Geeqie-svn mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geeqie-svn