Revert "Enable syncing of redraws to monitor refresh rate"
This reverts commit 6a51096304.
Turns out that dynamically changing the swap interval causes bad flicker
when rendering on X11 in a fullscreen window (or more generally, when
only a single X11 window is visible).
This commit is contained in:
@@ -348,15 +348,6 @@ glyph in video RAM so that font rendering is not a bottleneck. Interaction
|
|||||||
with child programs takes place in a separate thread from rendering, to improve
|
with child programs takes place in a separate thread from rendering, to improve
|
||||||
smoothness.
|
smoothness.
|
||||||
|
|
||||||
kitty goes to great lengths to reduce latency. In order to minimize latency,
|
|
||||||
kitty dynamically decides whether to sync updates to the monitor refresh rate
|
|
||||||
or not. When doing latency sensitive activities such as typing or selecting
|
|
||||||
with the mouse, kitty does not sync to the monitor refresh rate, as that limits
|
|
||||||
latency to a minimum of `17ms` for common monitors. However, when
|
|
||||||
scrolling or making other large scale changes to the screen, kitty syncs to the
|
|
||||||
monitor refresh rate, to avoid
|
|
||||||
link:https://en.wikipedia.org/wiki/Screen_tearing[screen tearing].
|
|
||||||
|
|
||||||
There are two parameters you can tune to adjust the performance. ``repaint_delay``
|
There are two parameters you can tune to adjust the performance. ``repaint_delay``
|
||||||
and ``input_delay``. These control the artificial delays introduced into the
|
and ``input_delay``. These control the artificial delays introduced into the
|
||||||
render loop to reduce CPU usage. See the link:kitty/kitty.conf[config file] for details.
|
render loop to reduce CPU usage. See the link:kitty/kitty.conf[config file] for details.
|
||||||
|
|||||||
@@ -605,7 +605,6 @@ render_os_window(OSWindow *os_window, double now, unsigned int active_window_id)
|
|||||||
Tab *tab = os_window->tabs + os_window->active_tab;
|
Tab *tab = os_window->tabs + os_window->active_tab;
|
||||||
BorderRects *br = &tab->border_rects;
|
BorderRects *br = &tab->border_rects;
|
||||||
draw_borders(br->vao_idx, br->num_border_rects, br->rect_buf, br->is_dirty, os_window->viewport_width, os_window->viewport_height);
|
draw_borders(br->vao_idx, br->num_border_rects, br->rect_buf, br->is_dirty, os_window->viewport_width, os_window->viewport_height);
|
||||||
bool needs_vsync = false;
|
|
||||||
if (TD.screen && os_window->num_tabs > 1) draw_cells(TD.vao_idx, 0, TD.xstart, TD.ystart, TD.dx, TD.dy, TD.screen, os_window, true);
|
if (TD.screen && os_window->num_tabs > 1) draw_cells(TD.vao_idx, 0, TD.xstart, TD.ystart, TD.dx, TD.dy, TD.screen, os_window, true);
|
||||||
for (unsigned int i = 0; i < tab->num_windows; i++) {
|
for (unsigned int i = 0; i < tab->num_windows; i++) {
|
||||||
Window *w = tab->windows + i;
|
Window *w = tab->windows + i;
|
||||||
@@ -619,11 +618,9 @@ render_os_window(OSWindow *os_window, double now, unsigned int active_window_id)
|
|||||||
double bell_left = global_state.opts.visual_bell_duration - (now - WD.screen->start_visual_bell_at);
|
double bell_left = global_state.opts.visual_bell_duration - (now - WD.screen->start_visual_bell_at);
|
||||||
set_maximum_wait(bell_left);
|
set_maximum_wait(bell_left);
|
||||||
}
|
}
|
||||||
if (!needs_vsync && (WD.screen->render_activity.large_change || WD.screen->render_activity.chars_written > 100)) needs_vsync = true;
|
|
||||||
WD.screen->render_activity.large_change = false; WD.screen->render_activity.chars_written = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
swap_window_buffers(os_window, needs_vsync);
|
swap_window_buffers(os_window);
|
||||||
br->is_dirty = false;
|
br->is_dirty = false;
|
||||||
os_window->last_active_tab = os_window->active_tab; os_window->last_num_tabs = os_window->num_tabs; os_window->last_active_window_id = active_window_id;
|
os_window->last_active_tab = os_window->active_tab; os_window->last_num_tabs = os_window->num_tabs; os_window->last_active_window_id = active_window_id;
|
||||||
os_window->focused_at_last_render = os_window->is_focused;
|
os_window->focused_at_last_render = os_window->is_focused;
|
||||||
|
|||||||
@@ -626,11 +626,7 @@ hide_mouse(OSWindow *w) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
swap_window_buffers(OSWindow *w, bool needs_vsync) {
|
swap_window_buffers(OSWindow *w) {
|
||||||
if (needs_vsync != w->vsync_enabled) {
|
|
||||||
glfwSwapInterval(needs_vsync ? 1 : 0);
|
|
||||||
w->vsync_enabled = needs_vsync;
|
|
||||||
}
|
|
||||||
glfwSwapBuffers(w->handle);
|
glfwSwapBuffers(w->handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -743,7 +739,7 @@ os_window_swap_buffers(PyObject UNUSED *self, PyObject *args) {
|
|||||||
for (size_t i = 0; i < global_state.num_os_windows; i++) {
|
for (size_t i = 0; i < global_state.num_os_windows; i++) {
|
||||||
OSWindow *w = global_state.os_windows + i;
|
OSWindow *w = global_state.os_windows + i;
|
||||||
if (w->id == os_window_id) {
|
if (w->id == os_window_id) {
|
||||||
swap_window_buffers(w, false); Py_RETURN_NONE;
|
swap_window_buffers(w); Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PyErr_SetString(PyExc_ValueError, "no such OSWindow");
|
PyErr_SetString(PyExc_ValueError, "no such OSWindow");
|
||||||
|
|||||||
@@ -123,7 +123,6 @@ screen_reset(Screen *self) {
|
|||||||
init_tabstops(self->alt_tabstops, self->columns);
|
init_tabstops(self->alt_tabstops, self->columns);
|
||||||
cursor_reset(self->cursor);
|
cursor_reset(self->cursor);
|
||||||
self->is_dirty = true;
|
self->is_dirty = true;
|
||||||
self->render_activity.large_change = true;
|
|
||||||
screen_cursor_position(self, 1, 1);
|
screen_cursor_position(self, 1, 1);
|
||||||
set_dynamic_color(self, 110, NULL);
|
set_dynamic_color(self, 110, NULL);
|
||||||
set_dynamic_color(self, 111, NULL);
|
set_dynamic_color(self, 111, NULL);
|
||||||
@@ -203,7 +202,6 @@ screen_resize(Screen *self, unsigned int lines, unsigned int columns) {
|
|||||||
self->cursor->y = num_content_lines;
|
self->cursor->y = num_content_lines;
|
||||||
if (self->cursor->y >= self->lines) { self->cursor->y = self->lines - 1; screen_index(self); }
|
if (self->cursor->y >= self->lines) { self->cursor->y = self->lines - 1; screen_index(self); }
|
||||||
}
|
}
|
||||||
self->render_activity.large_change = true;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,7 +354,6 @@ screen_draw(Screen *self, uint32_t och) {
|
|||||||
line_right_shift(self->linebuf->line, self->cursor->x, char_width);
|
line_right_shift(self->linebuf->line, self->cursor->x, char_width);
|
||||||
}
|
}
|
||||||
line_set_char(self->linebuf->line, self->cursor->x, ch, char_width, self->cursor, false);
|
line_set_char(self->linebuf->line, self->cursor->x, ch, char_width, self->cursor, false);
|
||||||
self->render_activity.chars_written += 1;
|
|
||||||
self->cursor->x++;
|
self->cursor->x++;
|
||||||
if (char_width == 2) {
|
if (char_width == 2) {
|
||||||
line_set_char(self->linebuf->line, self->cursor->x, 0, 0, self->cursor, true);
|
line_set_char(self->linebuf->line, self->cursor->x, 0, 0, self->cursor, true);
|
||||||
@@ -491,7 +488,6 @@ screen_toggle_screen_buffer(Screen *self) {
|
|||||||
}
|
}
|
||||||
screen_history_scroll(self, SCROLL_FULL, false);
|
screen_history_scroll(self, SCROLL_FULL, false);
|
||||||
self->is_dirty = true;
|
self->is_dirty = true;
|
||||||
self->render_activity.large_change = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void screen_normal_keypad_mode(Screen UNUSED *self) {} // Not implemented as this is handled by the GUI
|
void screen_normal_keypad_mode(Screen UNUSED *self) {} // Not implemented as this is handled by the GUI
|
||||||
@@ -728,8 +724,7 @@ screen_cursor_to_column(Screen *self, unsigned int column) {
|
|||||||
self->history_line_added_count++; \
|
self->history_line_added_count++; \
|
||||||
} \
|
} \
|
||||||
linebuf_clear_line(self->linebuf, bottom); \
|
linebuf_clear_line(self->linebuf, bottom); \
|
||||||
self->is_dirty = true; \
|
self->is_dirty = true;
|
||||||
self->render_activity.large_change = true;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
screen_index(Screen *self) {
|
screen_index(Screen *self) {
|
||||||
@@ -754,8 +749,7 @@ screen_scroll(Screen *self, unsigned int count) {
|
|||||||
linebuf_reverse_index(self->linebuf, top, bottom); \
|
linebuf_reverse_index(self->linebuf, top, bottom); \
|
||||||
linebuf_clear_line(self->linebuf, top); \
|
linebuf_clear_line(self->linebuf, top); \
|
||||||
INDEX_GRAPHICS(1) \
|
INDEX_GRAPHICS(1) \
|
||||||
self->is_dirty = true; \
|
self->is_dirty = true;
|
||||||
self->render_activity.large_change = true;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
screen_reverse_index(Screen *self) {
|
screen_reverse_index(Screen *self) {
|
||||||
@@ -980,7 +974,6 @@ screen_erase_in_display(Screen *self, unsigned int how, bool private) {
|
|||||||
linebuf_mark_line_dirty(self->linebuf, i);
|
linebuf_mark_line_dirty(self->linebuf, i);
|
||||||
}
|
}
|
||||||
self->is_dirty = true;
|
self->is_dirty = true;
|
||||||
self->render_activity.large_change = true;
|
|
||||||
}
|
}
|
||||||
if (how != 2) {
|
if (how != 2) {
|
||||||
screen_erase_in_line(self, how, private);
|
screen_erase_in_line(self, how, private);
|
||||||
@@ -990,7 +983,6 @@ screen_erase_in_display(Screen *self, unsigned int how, bool private) {
|
|||||||
if (self->scrolled_by != 0) {
|
if (self->scrolled_by != 0) {
|
||||||
self->scrolled_by = 0;
|
self->scrolled_by = 0;
|
||||||
self->scroll_changed = true;
|
self->scroll_changed = true;
|
||||||
self->render_activity.large_change = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1002,7 +994,6 @@ screen_insert_lines(Screen *self, unsigned int count) {
|
|||||||
if (top <= self->cursor->y && self->cursor->y <= bottom) {
|
if (top <= self->cursor->y && self->cursor->y <= bottom) {
|
||||||
linebuf_insert_lines(self->linebuf, count, self->cursor->y, bottom);
|
linebuf_insert_lines(self->linebuf, count, self->cursor->y, bottom);
|
||||||
self->is_dirty = true;
|
self->is_dirty = true;
|
||||||
self->render_activity.large_change = true;
|
|
||||||
screen_carriage_return(self);
|
screen_carriage_return(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1014,7 +1005,6 @@ screen_delete_lines(Screen *self, unsigned int count) {
|
|||||||
if (top <= self->cursor->y && self->cursor->y <= bottom) {
|
if (top <= self->cursor->y && self->cursor->y <= bottom) {
|
||||||
linebuf_delete_lines(self->linebuf, count, self->cursor->y, bottom);
|
linebuf_delete_lines(self->linebuf, count, self->cursor->y, bottom);
|
||||||
self->is_dirty = true;
|
self->is_dirty = true;
|
||||||
self->render_activity.large_change = true;
|
|
||||||
screen_carriage_return(self);
|
screen_carriage_return(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1712,7 +1702,6 @@ screen_history_scroll(Screen *self, int amt, bool upwards) {
|
|||||||
if (new_scroll != self->scrolled_by) {
|
if (new_scroll != self->scrolled_by) {
|
||||||
self->scrolled_by = new_scroll;
|
self->scrolled_by = new_scroll;
|
||||||
self->scroll_changed = true;
|
self->scroll_changed = true;
|
||||||
self->render_activity.large_change = true;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -51,12 +51,6 @@ typedef struct {
|
|||||||
} SavemodesBuffer;
|
} SavemodesBuffer;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
bool large_change;
|
|
||||||
unsigned int chars_written;
|
|
||||||
} RenderActivitity;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
|
|
||||||
@@ -90,7 +84,6 @@ typedef struct {
|
|||||||
pthread_mutex_t read_buf_lock, write_buf_lock;
|
pthread_mutex_t read_buf_lock, write_buf_lock;
|
||||||
|
|
||||||
CursorRenderInfo cursor_render_info;
|
CursorRenderInfo cursor_render_info;
|
||||||
RenderActivitity render_activity;
|
|
||||||
|
|
||||||
} Screen;
|
} Screen;
|
||||||
|
|
||||||
|
|||||||
@@ -114,7 +114,6 @@ typedef struct {
|
|||||||
bool is_damaged;
|
bool is_damaged;
|
||||||
uint32_t offscreen_texture_id;
|
uint32_t offscreen_texture_id;
|
||||||
unsigned int clear_count;
|
unsigned int clear_count;
|
||||||
bool vsync_enabled;
|
|
||||||
} OSWindow;
|
} OSWindow;
|
||||||
|
|
||||||
|
|
||||||
@@ -157,7 +156,7 @@ bool should_os_window_be_rendered(OSWindow* w);
|
|||||||
void set_dpi_from_os_window(OSWindow *w);
|
void set_dpi_from_os_window(OSWindow *w);
|
||||||
void wakeup_main_loop();
|
void wakeup_main_loop();
|
||||||
void event_loop_wait(double timeout);
|
void event_loop_wait(double timeout);
|
||||||
void swap_window_buffers(OSWindow *w, bool);
|
void swap_window_buffers(OSWindow *w);
|
||||||
void make_window_context_current(OSWindow *w);
|
void make_window_context_current(OSWindow *w);
|
||||||
void hide_mouse(OSWindow *w);
|
void hide_mouse(OSWindow *w);
|
||||||
void destroy_os_window(OSWindow *w);
|
void destroy_os_window(OSWindow *w);
|
||||||
|
|||||||
Reference in New Issue
Block a user