Implement paused rendering for cell data

This commit is contained in:
Kovid Goyal 2024-01-02 11:04:23 +05:30
parent aeb60edf55
commit b444b2ee36
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
4 changed files with 70 additions and 16 deletions

View file

@ -724,6 +724,7 @@ prepare_to_render_os_window(OSWindow *os_window, monotonic_t now, unsigned int *
Window *w = tab->windows + i;
#define WD w->render_data
if (w->visible && WD.screen) {
screen_check_pause_rendering(WD.screen, now);
*num_visible_windows += 1;
color_type window_bg = colorprofile_to_color(WD.screen->color_profile, WD.screen->color_profile->overridden.default_bg, WD.screen->color_profile->configured.default_bg).rgb;
if (*num_visible_windows == 1) first_window_bg = window_bg;

View file

@ -473,6 +473,7 @@ dealloc(Screen* self) {
PyMem_Free(self->overlay_line.original_line.gpu_cells);
Py_CLEAR(self->overlay_line.overlay_text);
PyMem_Free(self->main_tabstops);
Py_CLEAR(self->paused_rendering.linebuf);
free(self->selections.items);
free(self->url_ranges.items);
free_hyperlink_pool(self->hyperlink_pool);
@ -2362,19 +2363,38 @@ screen_request_capabilities(Screen *self, char c, const char *query) {
// Rendering {{{
void
screen_check_pause_rendering(Screen *self, monotonic_t now) {
if (self->paused_rendering.expires_at && now > self->paused_rendering.expires_at) screen_pause_rendering(self, false, 0);
}
bool
screen_pause_rendering(Screen *self, bool pause, int for_in_ms) {
if (!pause) {
if (!self->paused_rendering.expires_at) return false;
self->paused_rendering.expires_at = 0;
self->is_dirty = true;
return true;
}
if (self->paused_rendering.expires_at) return false;
if (for_in_ms <= 0) for_in_ms = 2000;
self->paused_rendering.expires_at = monotonic() + ms_to_monotonic_t(for_in_ms);
self->paused_rendering.inverted = self->modes.mDECSCNM ? true : false;
self->paused_rendering.scrolled_by = self->scrolled_by;
self->paused_rendering.cell_data_updated = false;
memcpy(&self->paused_rendering.cursor, self->cursor, sizeof(self->paused_rendering.cursor));
memcpy(&self->paused_rendering.color_profile, self->color_profile, sizeof(self->paused_rendering.color_profile));
if (!self->paused_rendering.linebuf || self->paused_rendering.linebuf->xnum != self->columns || self->paused_rendering.linebuf->ynum != self->lines) {
if (self->paused_rendering.linebuf) Py_CLEAR(self->paused_rendering.linebuf);
self->paused_rendering.linebuf = alloc_linebuf(self->lines, self->columns);
if (!self->paused_rendering.linebuf) { PyErr_Clear(); self->paused_rendering.expires_at = 0; return false; }
}
for (index_type y = 0; y < self->lines; y++) {
Line *src = visual_line_(self, y);
linebuf_init_line(self->paused_rendering.linebuf, y);
copy_line(src, self->linebuf->line);
self->paused_rendering.linebuf->line_attrs[y] = src->attrs;
}
return true;
}
@ -2571,6 +2591,22 @@ screen_update_only_line_graphics_data(Screen *self) {
void
screen_update_cell_data(Screen *self, void *address, FONTS_DATA_HANDLE fonts_data, bool cursor_has_moved) {
if (self->paused_rendering.expires_at) {
if (!self->paused_rendering.cell_data_updated) {
LineBuf *linebuf = self->paused_rendering.linebuf;
for (index_type y = 0; y < self->lines; y++) {
linebuf_init_line(linebuf, y);
if (linebuf->line->attrs.has_dirty_text) {
render_line(fonts_data, linebuf->line, y, &self->paused_rendering.cursor, self->disable_ligatures);
screen_render_line_graphics(self, linebuf->line, y);
if (linebuf->line->attrs.has_dirty_text && screen_has_marker(self)) mark_text_in_line(self->marker, linebuf->line);
linebuf_mark_line_clean(linebuf, y);
}
update_line_data(linebuf->line, y, address);
}
}
return;
}
const bool is_overlay_active = screen_is_overlay_active(self);
unsigned int history_line_added_count = self->history_line_added_count;
index_type lnum;

View file

@ -154,7 +154,9 @@ typedef struct {
monotonic_t expires_at;
Cursor cursor;
ColorProfile color_profile;
bool inverted;
bool inverted, cell_data_updated;
unsigned int scrolled_by;
LineBuf *linebuf;
} paused_rendering;
} Screen;
@ -268,6 +270,7 @@ bool screen_send_signal_for_key(Screen *, char key);
bool get_line_edge_colors(Screen *self, color_type *left, color_type *right);
bool parse_sgr(Screen *screen, const uint8_t *buf, unsigned int num, const char *report_name, bool is_deccara);
bool screen_pause_rendering(Screen *self, bool pause, int for_in_ms);
void screen_check_pause_rendering(Screen *self, monotonic_t now);
#define DECLARE_CH_SCREEN_HANDLER(name) void screen_##name(Screen *screen);
DECLARE_CH_SCREEN_HANDLER(bell)
DECLARE_CH_SCREEN_HANDLER(backspace)

View file

@ -389,12 +389,19 @@ cell_prepare_to_render(ssize_t vao_idx, Screen *screen, GLfloat xstart, GLfloat
bool disable_ligatures = screen->disable_ligatures == DISABLE_LIGATURES_CURSOR;
bool screen_resized = screen->last_rendered.columns != screen->columns || screen->last_rendered.lines != screen->lines;
if (screen->reload_all_gpu_data || screen->scroll_changed || screen->is_dirty || screen_resized || (disable_ligatures && cursor_pos_changed)) {
sz = sizeof(GPUCell) * screen->lines * screen->columns;
address = alloc_and_map_vao_buffer(vao_idx, sz, cell_data_buffer, GL_STREAM_DRAW, GL_WRITE_ONLY);
screen_update_cell_data(screen, address, fonts_data, disable_ligatures && cursor_pos_changed);
unmap_vao_buffer(vao_idx, cell_data_buffer); address = NULL;
#define update_cell_data \
sz = sizeof(GPUCell) * screen->lines * screen->columns; \
address = alloc_and_map_vao_buffer(vao_idx, sz, cell_data_buffer, GL_STREAM_DRAW, GL_WRITE_ONLY); \
screen_update_cell_data(screen, address, fonts_data, disable_ligatures && cursor_pos_changed); \
unmap_vao_buffer(vao_idx, cell_data_buffer); address = NULL; \
changed = true;
if (screen->paused_rendering.expires_at) {
if (!screen->paused_rendering.cell_data_updated) {
update_cell_data;
}
} else if (screen->reload_all_gpu_data || screen->scroll_changed || screen->is_dirty || screen_resized || (disable_ligatures && cursor_pos_changed)) {
update_cell_data;
}
if (cursor_pos_changed) {
@ -402,18 +409,25 @@ cell_prepare_to_render(ssize_t vao_idx, Screen *screen, GLfloat xstart, GLfloat
screen->last_rendered.cursor_y = cursor->y;
}
if (screen->reload_all_gpu_data || screen_resized || screen_is_selection_dirty(screen)) {
sz = (size_t)screen->lines * screen->columns;
address = alloc_and_map_vao_buffer(vao_idx, sz, selection_buffer, GL_STREAM_DRAW, GL_WRITE_ONLY);
screen_apply_selection(screen, address, sz);
unmap_vao_buffer(vao_idx, selection_buffer); address = NULL;
changed = true;
}
if (screen->paused_rendering.expires_at) {
if (!screen->paused_rendering.cell_data_updated) {
}
screen->paused_rendering.cell_data_updated = true;
screen->last_rendered.scrolled_by = screen->paused_rendering.scrolled_by;
} else {
if (screen->reload_all_gpu_data || screen_resized || screen_is_selection_dirty(screen)) {
sz = (size_t)screen->lines * screen->columns;
address = alloc_and_map_vao_buffer(vao_idx, sz, selection_buffer, GL_STREAM_DRAW, GL_WRITE_ONLY);
screen_apply_selection(screen, address, sz);
unmap_vao_buffer(vao_idx, selection_buffer); address = NULL;
changed = true;
}
if (grman_update_layers(screen->grman, screen->scrolled_by, xstart, ystart, dx, dy, screen->columns, screen->lines, screen->cell_size)) {
changed = true;
if (grman_update_layers(screen->grman, screen->scrolled_by, xstart, ystart, dx, dy, screen->columns, screen->lines, screen->cell_size)) {
changed = true;
}
screen->last_rendered.scrolled_by = screen->scrolled_by;
}
screen->last_rendered.scrolled_by = screen->scrolled_by;
screen->last_rendered.columns = screen->columns;
screen->last_rendered.lines = screen->lines;
return changed;