[eog] EogScrollView: Implement simple two-pass filtering



commit 88c4f54eb9cee69b1eebef462df27f76119bec62
Author: Felix Riemann <friemann gnome org>
Date:   Mon Feb 15 20:49:48 2016 +0100

    EogScrollView: Implement simple two-pass filtering
    
    Show the filtered image only after a short time.
    This should improve the UI's responsiveness quite a bit.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=665897

 src/eog-scroll-view.c |   66 ++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 62 insertions(+), 4 deletions(-)
---
diff --git a/src/eog-scroll-view.c b/src/eog-scroll-view.c
index ded5572..4539498 100644
--- a/src/eog-scroll-view.c
+++ b/src/eog-scroll-view.c
@@ -171,6 +171,10 @@ struct _EogScrollViewPrivate {
        GtkWidget *right_revealer;
        GtkWidget *bottom_revealer;
        GSource   *overlay_timeout_source;
+
+       /* Two-pass filtering */
+       GSource *hq_redraw_timeout_source;
+       gboolean force_unfiltered;
 };
 
 static void scroll_by (EogScrollView *view, int xofs, int yofs);
@@ -1249,6 +1253,44 @@ eog_scroll_view_focus_out_event (GtkWidget     *widget,
        return FALSE;
 }
 
+static gboolean _hq_redraw_cb (gpointer user_data)
+{
+       EogScrollViewPrivate *priv = EOG_SCROLL_VIEW (user_data)->priv;
+
+       priv->force_unfiltered = FALSE;
+       gtk_widget_queue_draw (GTK_WIDGET (priv->display));
+
+       return G_SOURCE_REMOVE;
+}
+
+static void
+_clear_hq_redraw_timeout (EogScrollView *view)
+{
+       EogScrollViewPrivate *priv = view->priv;
+
+       if (priv->hq_redraw_timeout_source != NULL) {
+               g_source_unref (priv->hq_redraw_timeout_source);
+               g_source_destroy (priv->hq_redraw_timeout_source);
+       }
+
+       priv->hq_redraw_timeout_source = NULL;
+}
+
+static void
+_set_hq_redraw_timeout (EogScrollView *view)
+{
+       GSource *source;
+
+       _clear_hq_redraw_timeout (view);
+
+       source = g_timeout_source_new (200);
+       g_source_set_callback (source, &_hq_redraw_cb, view, NULL);
+
+       g_source_attach (source, NULL);
+
+       view->priv->hq_redraw_timeout_source = source;
+}
+
 static gboolean
 display_draw (GtkWidget *widget, cairo_t *cr, gpointer data)
 {
@@ -1361,13 +1403,28 @@ display_draw (GtkWidget *widget, cairo_t *cr, gpointer data)
        } else
 #endif /* HAVE_RSVG */
        {
+               cairo_filter_t interp_type;
+
+               if(!DOUBLE_EQUAL(priv->zoom, 1.0) && priv->force_unfiltered)
+               {
+                       interp_type = CAIRO_FILTER_NEAREST;
+                       _set_hq_redraw_timeout(view);
+               }
+               else
+               {
+                       if (is_zoomed_in (view))
+                               interp_type = priv->interp_type_in;
+                       else
+                               interp_type = priv->interp_type_out;
+
+                       _clear_hq_redraw_timeout (view);
+                       priv->force_unfiltered = TRUE;
+               }
                cairo_scale (cr, priv->zoom, priv->zoom);
                cairo_set_source_surface (cr, priv->surface, xofs/priv->zoom, yofs/priv->zoom);
                cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_PAD);
-               if (is_zoomed_in (view))
-                       cairo_pattern_set_filter (cairo_get_source (cr), priv->interp_type_in);
-               else if (is_zoomed_out (view))
-                       cairo_pattern_set_filter (cairo_get_source (cr), priv->interp_type_out);
+               if (is_zoomed_in (view) || is_zoomed_out (view))
+                       cairo_pattern_set_filter (cairo_get_source (cr), interp_type);
 
                cairo_paint (cr);
        }
@@ -2356,6 +2413,7 @@ eog_scroll_view_dispose (GObject *object)
        priv = view->priv;
 
        _clear_overlay_timeout (view);
+       _clear_hq_redraw_timeout (view);
 
        if (priv->idle_id != 0) {
                g_source_remove (priv->idle_id);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]