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

Reply via email to