mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-03-21 05:33:45 -04:00
main: use a timer FD to delay render refresh after client data
This ensures we never wait *longer* than 1ms (previously, we could end up doing multiple polls, each with a timeout value of 1ms - thereby potentially delaying the refresh indefinitely).
This commit is contained in:
parent
fb018eb64e
commit
9f7ea6292e
1 changed files with 23 additions and 10 deletions
33
main.c
33
main.c
|
|
@ -14,6 +14,7 @@
|
||||||
#include <sys/sysinfo.h>
|
#include <sys/sysinfo.h>
|
||||||
#include <sys/prctl.h>
|
#include <sys/prctl.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <freetype/tttables.h>
|
#include <freetype/tttables.h>
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
|
|
@ -888,8 +889,9 @@ main(int argc, char *const *argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool timeout_is_armed = false;
|
||||||
|
int timeout_fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK | TFD_CLOEXEC);
|
||||||
|
|
||||||
int timeout_ms = -1;
|
|
||||||
while (true) {
|
while (true) {
|
||||||
struct pollfd fds[] = {
|
struct pollfd fds[] = {
|
||||||
{.fd = wl_display_get_fd(term.wl.display), .events = POLLIN},
|
{.fd = wl_display_get_fd(term.wl.display), .events = POLLIN},
|
||||||
|
|
@ -897,10 +899,11 @@ main(int argc, char *const *argv)
|
||||||
{.fd = term.kbd.repeat.fd, .events = POLLIN},
|
{.fd = term.kbd.repeat.fd, .events = POLLIN},
|
||||||
{.fd = term.flash.fd, .events = POLLIN},
|
{.fd = term.flash.fd, .events = POLLIN},
|
||||||
{.fd = term.blink.fd, .events = POLLIN},
|
{.fd = term.blink.fd, .events = POLLIN},
|
||||||
|
{.fd = timeout_fd, .events = POLLIN},
|
||||||
};
|
};
|
||||||
|
|
||||||
wl_display_flush(term.wl.display);
|
wl_display_flush(term.wl.display);
|
||||||
int pret = poll(fds, sizeof(fds) / sizeof(fds[0]), timeout_ms);
|
int pret = poll(fds, sizeof(fds) / sizeof(fds[0]), -1);
|
||||||
|
|
||||||
if (pret == -1) {
|
if (pret == -1) {
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
|
|
@ -910,13 +913,19 @@ main(int argc, char *const *argv)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pret == 0 || (timeout_ms != -1 && !(fds[1].revents & POLLIN))) {
|
if (fds[5].revents & POLLIN) {
|
||||||
/* Delayed rendering */
|
assert(timeout_is_armed);
|
||||||
render_refresh(&term);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset poll timeout to infinity */
|
uint64_t unused;
|
||||||
timeout_ms = -1;
|
ssize_t ret = read(timeout_fd, &unused, sizeof(unused));
|
||||||
|
|
||||||
|
if (ret < 0 && errno != EAGAIN)
|
||||||
|
LOG_ERRNO("failed to read timeout timer");
|
||||||
|
else if (ret > 0) {
|
||||||
|
timeout_is_armed = false;
|
||||||
|
render_refresh(&term);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (fds[0].revents & POLLIN) {
|
if (fds[0].revents & POLLIN) {
|
||||||
wl_display_dispatch(term.wl.display);
|
wl_display_dispatch(term.wl.display);
|
||||||
|
|
@ -968,7 +977,10 @@ main(int argc, char *const *argv)
|
||||||
* ourselves we just received keyboard input, and in
|
* ourselves we just received keyboard input, and in
|
||||||
* this case *not* delay rendering?
|
* this case *not* delay rendering?
|
||||||
*/
|
*/
|
||||||
timeout_ms = 1;
|
if (!timeout_is_armed) {
|
||||||
|
timerfd_settime(timeout_fd, 0, &(struct itimerspec){.it_value = {.tv_nsec = 1000000}}, NULL);
|
||||||
|
timeout_is_armed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1039,9 +1051,10 @@ main(int argc, char *const *argv)
|
||||||
render_refresh(&term);
|
render_refresh(&term);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
close(timeout_fd);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
mtx_lock(&term.render.workers.lock);
|
mtx_lock(&term.render.workers.lock);
|
||||||
assert(tll_length(term.render.workers.queue) == 0);
|
assert(tll_length(term.render.workers.queue) == 0);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue