# HG changeset patch # User nadvornik # Date 1220296712 0 # Node ID f10b680b4baaeff047a401a88f2d6e7a260f1e9d # Parent 1a4b18c585568d9fddeb90bd801c902aefa36c97 improved pixbuf draw priority control diff -r 1a4b18c58556 -r f10b680b4baa src/pixbuf-renderer.c --- 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); } } diff -r 1a4b18c58556 -r f10b680b4baa src/pixbuf-renderer.h --- 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;