macOS: Fix rendering frames-per-second very low when processing large amounts of input in small chunks
We do this by debouncing wakeup events sent to the main loop by the I/O thread. Use in the input_delay time to debounce. Apparently processing wakeup events is very expensive in Cocoa. Fixes #1082
This commit is contained in:
parent
adf9c4fc5f
commit
40b355e593
@ -29,6 +29,9 @@ Changelog
|
|||||||
|
|
||||||
- macOS: Fix IME input for east asian languages (:iss:`910`)
|
- macOS: Fix IME input for east asian languages (:iss:`910`)
|
||||||
|
|
||||||
|
- macOS: Fix rendering frames-per-second very low when processing
|
||||||
|
large amounts of input in small chunks (:pull:`1082`)
|
||||||
|
|
||||||
- Fix expansion of env vars not working in the :opt:`env` directive
|
- Fix expansion of env vars not working in the :opt:`env` directive
|
||||||
(:iss:`1075`)
|
(:iss:`1075`)
|
||||||
|
|
||||||
|
|||||||
@ -984,7 +984,8 @@ io_loop(void *data) {
|
|||||||
// The I/O thread loop
|
// The I/O thread loop
|
||||||
size_t i;
|
size_t i;
|
||||||
int ret;
|
int ret;
|
||||||
bool has_more, data_received;
|
bool has_more, data_received, has_pending_wakeups = false;
|
||||||
|
double last_main_loop_wakeup_at = -1, now = -1;
|
||||||
Screen *screen;
|
Screen *screen;
|
||||||
ChildMonitor *self = (ChildMonitor*)data;
|
ChildMonitor *self = (ChildMonitor*)data;
|
||||||
set_thread_name("KittyChildMon");
|
set_thread_name("KittyChildMon");
|
||||||
@ -1003,7 +1004,14 @@ io_loop(void *data) {
|
|||||||
fds[EXTRA_FDS + i].events = (screen->read_buf_sz < READ_BUF_SZ ? POLLIN : 0) | (screen->write_buf_used ? POLLOUT : 0);
|
fds[EXTRA_FDS + i].events = (screen->read_buf_sz < READ_BUF_SZ ? POLLIN : 0) | (screen->write_buf_used ? POLLOUT : 0);
|
||||||
screen_mutex(unlock, read); screen_mutex(unlock, write);
|
screen_mutex(unlock, read); screen_mutex(unlock, write);
|
||||||
}
|
}
|
||||||
|
if (has_pending_wakeups) {
|
||||||
|
now = monotonic();
|
||||||
|
double time_delta = OPT(input_delay) - (now - last_main_loop_wakeup_at);
|
||||||
|
if (time_delta > 0) ret = poll(fds, self->count + EXTRA_FDS, -1);
|
||||||
|
else ret = 0;
|
||||||
|
} else {
|
||||||
ret = poll(fds, self->count + EXTRA_FDS, -1);
|
ret = poll(fds, self->count + EXTRA_FDS, -1);
|
||||||
|
}
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
if (fds[0].revents && POLLIN) drain_fd(fds[0].fd); // wakeup
|
if (fds[0].revents && POLLIN) drain_fd(fds[0].fd); // wakeup
|
||||||
if (fds[1].revents && POLLIN) {
|
if (fds[1].revents && POLLIN) {
|
||||||
@ -1047,8 +1055,17 @@ io_loop(void *data) {
|
|||||||
perror("Call to poll() failed");
|
perror("Call to poll() failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (data_received) wakeup_main_loop();
|
#define WAKEUP { wakeup_main_loop(); last_main_loop_wakeup_at = now; has_pending_wakeups = false; }
|
||||||
|
// we only wakeup the main loop after input_delay as wakeup is an expensive operation
|
||||||
|
// on some platforms, such as cocoa
|
||||||
|
if (data_received) {
|
||||||
|
if ((now = monotonic()) - last_main_loop_wakeup_at > OPT(input_delay)) WAKEUP
|
||||||
|
else has_pending_wakeups = true;
|
||||||
|
} else {
|
||||||
|
if (has_pending_wakeups && (now = monotonic()) - last_main_loop_wakeup_at > OPT(input_delay)) WAKEUP
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
#undef WAKEUP
|
||||||
children_mutex(lock);
|
children_mutex(lock);
|
||||||
for (i = 0; i < self->count; i++) children[i].needs_removal = true;
|
for (i = 0; i < self->count; i++) children[i].needs_removal = true;
|
||||||
remove_children(self);
|
remove_children(self);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user