commit: 95033753be32e93915ddce14ea41b8765b665771
parent: b7261c84aa3af984d5a7e5f5239c4173255a215d
Author: Christoph Lohmann <20h@r-36.net>
Date: Fri, 15 Feb 2013 19:10:22 +0100
Adding a more efficient drawing code.
Thanks Mihail Zenkov <mihail.zenkov@gmail.com> for giving the hint!
Diffstat:
M | config.def.h | 5 | ++++- |
M | st.c | 65 | ++++++++++++++++++++++++++++++++++++++--------------------------- |
2 files changed, 42 insertions(+), 28 deletions(-)
diff --git 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
@@ -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;
+ }
}
}