From baa4e0b1c446c7c5ded232dba1b943004309f349 Mon Sep 17 00:00:00 2001 From: Felix Riemann Date: Mon, 15 Feb 2016 20:49:48 +0100 Subject: 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 origin commit: https://gitlab.gnome.org/GNOME/eog/commit/88c4f54 https://gitlab.gnome.org/GNOME/eog/commit/8169e0a --- src/eom-scroll-view.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/src/eom-scroll-view.c b/src/eom-scroll-view.c index 491796c..c3a476b 100644 --- a/src/eom-scroll-view.c +++ b/src/eom-scroll-view.c @@ -147,6 +147,10 @@ struct _EomScrollViewPrivate { GdkRGBA *override_bg_color; cairo_surface_t *background_surface; + + /* Two-pass filtering */ + GSource *hq_redraw_timeout_source; + gboolean force_unfiltered; }; static void scroll_by (EomScrollView *view, int xofs, int yofs); @@ -1182,6 +1186,45 @@ eom_scroll_view_focus_out_event (GtkWidget *widget, return FALSE; } +static gboolean _hq_redraw_cb (gpointer user_data) +{ + EomScrollViewPrivate *priv = EOM_SCROLL_VIEW (user_data)->priv; + + priv->force_unfiltered = FALSE; + gtk_widget_queue_draw (GTK_WIDGET (priv->display)); + + priv->hq_redraw_timeout_source = NULL; + return G_SOURCE_REMOVE; +} + +static void +_clear_hq_redraw_timeout (EomScrollView *view) +{ + EomScrollViewPrivate *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 (EomScrollView *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) { @@ -1307,13 +1350,29 @@ 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); } @@ -1853,6 +1912,8 @@ eom_scroll_view_dispose (GObject *object) view = EOM_SCROLL_VIEW (object); priv = view->priv; + _clear_hq_redraw_timeout (view); + if (priv->idle_id != 0) { g_source_remove (priv->idle_id); priv->idle_id = 0; -- cgit v1.2.1