changeset 1030:f10b680b4baa

improved pixbuf draw priority control
author nadvornik
date Mon, 01 Sep 2008 19:18:32 +0000
parents 1a4b18c58556
children 999919edcb7b
files src/pixbuf-renderer.c src/pixbuf-renderer.h
diffstat 2 files changed, 65 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/pixbuf-renderer.c	Mon Sep 01 17:29:07 2008 +0000
+++ b/src/pixbuf-renderer.c	Mon Sep 01 19:18:32 2008 +0000
@@ -221,6 +221,7 @@
 static void pr_signals_connect(PixbufRenderer *pr);
 static void pr_size_cb(GtkWidget *widget, GtkAllocation *allocation, gpointer data);
 static void pixbuf_renderer_paint(PixbufRenderer *pr, GdkRectangle *area);
+static gint pr_queue_draw_idle_cb(gpointer data);
 
 
 /*
@@ -2688,12 +2689,72 @@
  *-------------------------------------------------------------------
  */
 
+static gint pr_get_queued_area(GList *work)
+{
+	gint area = 0;
+	
+	while (work) 
+		{
+		QueueData *qd = work->data;
+		area += qd->w * qd->h;
+		work = work->next;
+		}
+	return area;
+}
+
+
+static gint pr_queue_schedule_next_draw(PixbufRenderer *pr, gboolean force_set)
+{
+	gfloat percent;
+	gint visible_area = pr->vis_width * pr->vis_height;
+	
+	if (!pr->loading)
+		{
+		/* 2pass prio */ 
+		DEBUG_2("redraw priority 2pass\n");
+		pr->draw_idle_id = g_idle_add_full(G_PRIORITY_HIGH_IDLE, pr_queue_draw_idle_cb, pr, NULL);
+		return FALSE;
+		}
+	
+	if (visible_area == 0)
+		{
+		/* not known yet */
+		percent = 100.0;
+		}
+	else
+		{
+		percent = 100.0 * pr_get_queued_area(pr->draw_queue) / visible_area;
+		}
+	
+	if (percent > 10.0)
+		{
+		/* we have enough data for starting intensive redrawing */
+		DEBUG_2("redraw priority high %f\n", percent);
+		pr->draw_idle_id = g_idle_add_full(GDK_PRIORITY_REDRAW, pr_queue_draw_idle_cb, pr, NULL);
+		return FALSE;
+		}
+	
+	if (percent < 1.0 || force_set)
+		{
+		/* queue is (almost) empty, wait  50 ms*/
+		DEBUG_2("redraw priority wait %f\n", percent);
+		pr->draw_idle_id = g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE, 50, pr_queue_draw_idle_cb, pr, NULL);
+		return FALSE;
+		}
+	
+	/* keep the same priority as before */
+	DEBUG_2("redraw priority no change %f\n", percent);
+	return TRUE;
+}
+		
+
 static gint pr_queue_draw_idle_cb(gpointer data)
 {
 	PixbufRenderer *pr = data;
 	QueueData *qd;
 	gint fast;
 
+
 	if ((!pr->pixbuf && !pr->source_tiles_enabled) ||
 	    (!pr->draw_queue && !pr->draw_queue_2pass) ||
 	    pr->draw_idle_id == -1)
@@ -2715,10 +2776,7 @@
 			{
 			/* still loading, wait till done (also drops the higher priority) */
 
-			pr->draw_idle_id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
-							   pr_queue_draw_idle_cb, pr, NULL);
-			pr->draw_idle_high = FALSE;
-			return FALSE;
+			return pr_queue_schedule_next_draw(pr, FALSE);
 			}
 
 		qd = pr->draw_queue_2pass->data;
@@ -2779,7 +2837,7 @@
 		return FALSE;
 		}
 
-	return TRUE;
+		return pr_queue_schedule_next_draw(pr, FALSE);
 }
 
 static void pr_queue_list_free(GList *list)
@@ -2967,12 +3025,10 @@
 	if (w < 1 || h < 1) return;
 
 	if (pr_queue_to_tiles(pr, nx, ny, w, h, clamp, render, new_data, only_existing) &&
-	    ((!pr->draw_queue && !pr->draw_queue_2pass) || pr->draw_idle_id == -1 || !pr->draw_idle_high))
+	    ((!pr->draw_queue && !pr->draw_queue_2pass) || pr->draw_idle_id == -1))
 		{
 		if (pr->draw_idle_id != -1) g_source_remove(pr->draw_idle_id);
-		pr->draw_idle_id = g_idle_add_full(GDK_PRIORITY_REDRAW,
-						   pr_queue_draw_idle_cb, pr, NULL);
-		pr->draw_idle_high = TRUE;
+		pr_queue_schedule_next_draw(pr, TRUE);
 		}
 }
 
--- a/src/pixbuf-renderer.h	Mon Sep 01 17:29:07 2008 +0000
+++ b/src/pixbuf-renderer.h	Mon Sep 01 19:18:32 2008 +0000
@@ -109,7 +109,6 @@
 	GList *draw_queue_2pass;/* list when 2 pass is enabled */
 
 	gint draw_idle_id;
-	gint draw_idle_high;	/* current idle_id has high priority */
 
 	gboolean in_drag;
 	gint drag_last_x;