From: Andre Noll Date: Mon, 6 Jan 2014 20:12:38 +0000 (+0000) Subject: gui: Speed up window refresh. X-Git-Tag: v0.5.3~12^2~5 X-Git-Url: http://git.tue.mpg.de/?a=commitdiff_plain;h=9cf149617f6de5a4a16f5f2af39bd532310246dc;p=paraslash.git gui: Speed up window refresh. We had way too many calls to wrefresh() which copies the named window to the physical terminal screen. This slows down the display considerably, especially on slow machines. It is more efficient to perform the copy only once per scheduler iteration. So this commit adds a flag "needs_update" to struct gui_window, and all callers to wrefresh() are changed to call refresh_window() instead. This new function is much cheaper since it only turns on the needs_update flag but does nothing else. In input_post_select() we check which windows have the flag set and repaint those windows using wnoutrefresh() and then doupdate(). This two-step approach is described in the curs_refresh(3X) man page as more efficient then calling wrefresh() for each window separately since it avoids alternating calls to wnoutrefresh() and doupdate(). --- diff --git a/gui.c b/gui.c index 8d84e463..4f536c5d 100644 --- a/gui.c +++ b/gui.c @@ -32,6 +32,7 @@ static char *stat_content[NUM_STAT_ITEMS]; static struct gui_window { WINDOW *win; + bool needs_update; } top, bot, sb, in, sep; #define RINGBUFFER_SIZE 512 @@ -296,6 +297,17 @@ static int align_str(WINDOW* win, char *str, unsigned int len, return 1; } +static void refresh_window(struct gui_window *gw) +{ + gw->needs_update = true; +} + +static bool window_update_needed(void) +{ + return top.needs_update || bot.needs_update || sb.needs_update || + in.needs_update || sep.needs_update; +} + __printf_2_3 static void print_in_bar(int color, const char *fmt,...) { char *msg; @@ -310,7 +322,7 @@ __printf_2_3 static void print_in_bar(int color, const char *fmt,...) wmove(in.win, 0, 0); align_str(in.win, msg, get_num_cols(&in), LEFT); free(msg); - wrefresh(in.win); + refresh_window(&in); } static void print_status_bar(void) @@ -406,7 +418,7 @@ static void redraw_bot_win(void) waddstr(bot.win, rbe->msg); } out: - wrefresh(bot.win); + refresh_window(&bot); } static void rb_add_entry(int color, char *msg) @@ -453,7 +465,7 @@ __printf_2_3 static void outputf(int color, const char* fmt,...) xvasprintf(&msg, fmt, ap); va_end(ap); rb_add_entry(color, msg); - wrefresh(bot.win); + refresh_window(&bot); } static int add_output_line(char *line, void *data) @@ -480,7 +492,7 @@ static __printf_2_3 void curses_log(int ll, const char *fmt,...) if (bytes > 0 && msg[bytes - 1] == '\n') msg[bytes - 1] = '\0'; /* cut trailing newline */ rb_add_entry(color, msg); - wrefresh(bot.win); + refresh_window(&bot); } else if (exec_pid <= 0) /* no external command running */ vfprintf(stderr, fmt, ap); va_end(ap); @@ -522,11 +534,10 @@ static void print_stat_item(int i) return; tmp = make_message("%s%s%s", d.prefix, c, d.postfix); wmove(top.win, d.y * top_lines / 100, d.x * COLS / 100); - wrefresh(top.win); wattron(top.win, COLOR_PAIR(i + 1)); align_str(top.win, tmp, d.len * COLS / 100, d.align); free(tmp); - wrefresh(top.win); + refresh_window(&top); } static int update_item(int item_num, char *buf) @@ -959,7 +970,7 @@ static int exec_post_select(struct sched *s, struct task *t) ct->cbo[i] = for_each_line(ct->flags[i], ct->command_buf[i], ct->cbo[i], add_output_line, &i); if (sz != ct->cbo[i]) { /* at least one line found */ - wrefresh(bot.win); + refresh_window(&bot); ct->flags[i] = 0; } if (ret < 0 || exec_pid == 0) { @@ -986,6 +997,8 @@ static void input_pre_select(struct sched *s, __a_unused struct task *t) { if (exec_status() != EXEC_XCMD) para_fd_set(STDIN_FILENO, &s->rfds, &s->max_fileno); + if (window_update_needed()) + sched_min_delay(s); } /* read from command pipe and print data to bot window */ @@ -1084,6 +1097,21 @@ static int input_post_select(__a_unused struct sched *s, __a_unused struct task if (exs == EXEC_XCMD) return 0; + if (window_update_needed()) { + if (top.needs_update) + assert(wnoutrefresh(top.win) == OK); + if (bot.needs_update) + assert(wnoutrefresh(bot.win) == OK); + if (sep.needs_update) + assert(wnoutrefresh(sep.win) == OK); + if (sb.needs_update) + assert(wnoutrefresh(sb.win) == OK); + if (in.needs_update) + assert(wnoutrefresh(in.win) == OK); + doupdate(); + top.needs_update = bot.needs_update = sb.needs_update = + in.needs_update = sep.needs_update = false; + } ret = wgetch(top.win); if (ret == ERR || ret == KEY_RESIZE) return 0; @@ -1201,7 +1229,7 @@ static void com_scroll_down(void) wmove(bot.win, bot_lines - rbe_lines, 0); wattron(bot.win, COLOR_PAIR(rbe->color)); waddstr(bot.win, rbe->msg); - wrefresh(bot.win); + refresh_window(&bot); print_scroll_msg(); } @@ -1238,7 +1266,7 @@ static void com_scroll_up(void) break; i--; } - wrefresh(bot.win); + refresh_window(&bot); print_scroll_msg(); return; err_out: