From 95033753be32e93915ddce14ea41b8765b665771 Mon Sep 17 00:00:00 2001 From: Christoph Lohmann <20h@r-36.net> Date: Fri, 15 Feb 2013 19:10:22 +0100 Subject: Adding a more efficient drawing code. Thanks Mihail Zenkov for giving the hint! --- config.def.h | 5 ++++- st.c | 65 +++++++++++++++++++++++++++++++++++------------------------- 2 files changed, 42 insertions(+), 28 deletions(-) diff --git a/config.def.h b/config.def.h index 684adf7..8732ca3 100644 --- a/config.def.h +++ b/config.def.h @@ -9,10 +9,13 @@ static char font[] = "Liberation Mono:pixelsize=12:antialias=false:autohint=fals static int borderpx = 2; static char shell[] = "/bin/sh"; -/* double-click timeout (in milliseconds) between clicks for selection */ +/* timeouts (in milliseconds) */ static unsigned int doubleclicktimeout = 300; static unsigned int tripleclicktimeout = 600; +/* frames per second st should at maximum draw to the screen */ +static unsigned int framespersecond = 60; + /* TERM value */ static char termname[] = "st-256color"; diff --git a/st.c b/st.c index 8206001..f4b419e 100644 --- a/st.c +++ b/st.c @@ -3166,10 +3166,12 @@ void run(void) { XEvent ev; fd_set rfd; - int xfd = XConnectionNumber(xw.dpy), i; - struct timeval drawtimeout, *tv = NULL; + int xfd = XConnectionNumber(xw.dpy); + struct timeval drawtimeout, *tv = NULL, now, last; - for(i = 0;; i++) { + gettimeofday(&last, NULL); + + for(;;) { FD_ZERO(&rfd); FD_SET(cmdfd, &rfd); FD_SET(xfd, &rfd); @@ -3179,35 +3181,44 @@ run(void) { die("select failed: %s\n", SERRNO); } - /* - * Stop after a certain number of reads so the user does not - * feel like the system is stuttering. - */ - if(i < 1000 && FD_ISSET(cmdfd, &rfd)) { - ttyread(); + gettimeofday(&now, NULL); + /* usecs until (next) frame */ + drawtimeout.tv_sec = 0; + drawtimeout.tv_usec = \ + ((1000/framespersecond) - TIMEDIFF(now, last)) * 1000; - /* - * Just wait a bit so it isn't disturbing the - * user and the system is able to write something. - */ - drawtimeout.tv_sec = 0; - drawtimeout.tv_usec = 5; - tv = &drawtimeout; - continue; + /* Let us draw a frame. */ + if(drawtimeout.tv_usec <= 0) { + draw(); + XFlush(xw.dpy); + + last = now; + tv = NULL; } - i = 0; - tv = NULL; - while(XPending(xw.dpy)) { - XNextEvent(xw.dpy, &ev); - if(XFilterEvent(&ev, None)) - continue; - if(handler[ev.type]) - (handler[ev.type])(&ev); + if(FD_ISSET(cmdfd, &rfd)) + ttyread(); + + if(FD_ISSET(xfd, &rfd)) { + while(XPending(xw.dpy)) { + XNextEvent(xw.dpy, &ev); + if(XFilterEvent(&ev, None)) + continue; + if(handler[ev.type]) + (handler[ev.type])(&ev); + } + + if(drawtimeout.tv_usec <= 0) { + draw(); + XFlush(xw.dpy); + } } - draw(); - XFlush(xw.dpy); + /* There is still some time to wait until next frame. */ + if(drawtimeout.tv_usec > 0) { + tv = &drawtimeout; + continue; + } } } -- cgit v1.2.3