Pause selection rendering

This commit is contained in:
Kovid Goyal 2024-01-02 14:45:36 +05:30
parent 7c5e011fe6
commit f596351bc1
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
4 changed files with 41 additions and 14 deletions

View file

@ -384,7 +384,7 @@ HANDLER(handle_move_event) {
bool cell_half_changed = false;
if (!set_mouse_position(w, &mouse_cell_changed, &cell_half_changed)) return;
Screen *screen = w->render_data.screen;
if(OPT(detect_urls)) detect_url(screen, w->mouse_pos.cell_x, w->mouse_pos.cell_y);
if (OPT(detect_urls)) detect_url(screen, w->mouse_pos.cell_x, w->mouse_pos.cell_y);
bool in_tracking_mode = (
screen->modes.mouse_tracking_mode == ANY_MODE ||
(screen->modes.mouse_tracking_mode == MOTION_MODE && button >= 0));

View file

@ -476,6 +476,8 @@ dealloc(Screen* self) {
Py_CLEAR(self->paused_rendering.linebuf);
free(self->selections.items);
free(self->url_ranges.items);
free(self->paused_rendering.url_ranges.items);
free(self->paused_rendering.selections.items);
free_hyperlink_pool(self->hyperlink_pool);
free(self->as_ansi_buf.buf);
free(self->last_rendered_window_char.canvas);
@ -2368,6 +2370,18 @@ 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);
}
static bool
copy_selections(Selections *dest, const Selections *src) {
if (dest->capacity < src->count) {
dest->items = realloc(dest->items, sizeof(dest->items[0]) * src->count);
if (!dest->items) { dest->capacity = 0; dest->count = 0; return false; }
dest->capacity = src->count;
}
dest->count = src->count;
for (unsigned i = 0; i < dest->count; i++) memcpy(dest->items + i, src->items + i, sizeof(dest->items[0]));
return true;
}
bool
screen_pause_rendering(Screen *self, bool pause, int for_in_ms) {
if (!pause) {
@ -2395,6 +2409,8 @@ screen_pause_rendering(Screen *self, bool pause, int for_in_ms) {
copy_line(src, self->linebuf->line);
self->paused_rendering.linebuf->line_attrs[y] = src->attrs;
}
copy_selections(&self->paused_rendering.selections, &self->selections);
copy_selections(&self->paused_rendering.url_ranges, &self->url_ranges);
return true;
}
@ -2827,9 +2843,13 @@ iteration_data_is_empty(const Screen *self, const IterationData *idata) {
static void
apply_selection(Screen *self, uint8_t *data, Selection *s, uint8_t set_mask) {
iteration_data(s, &s->last_rendered, self->columns, -self->historybuf->count, self->scrolled_by);
Line *line;
for (int y = MAX(0, s->last_rendered.y); y < s->last_rendered.y_limit && y < (int)self->lines; y++) {
Line *line = visual_line_(self, y);
if (self->paused_rendering.expires_at) {
linebuf_init_line(self->paused_rendering.linebuf, y);
line = self->paused_rendering.linebuf->line;
} else line = visual_line_(self, y);
uint8_t *line_start = data + self->columns * y;
XRange xr = xrange_for_iteration(&s->last_rendered, y, line);
for (index_type x = xr.x; x < xr.x_limit; x++) line_start[x] |= set_mask;
@ -2853,16 +2873,16 @@ screen_has_selection(Screen *self) {
void
screen_apply_selection(Screen *self, void *address, size_t size) {
memset(address, 0, size);
for (size_t i = 0; i < self->selections.count; i++) {
apply_selection(self, address, self->selections.items + i, 1);
}
self->selections.last_rendered_count = self->selections.count;
for (size_t i = 0; i < self->url_ranges.count; i++) {
Selection *s = self->url_ranges.items + i;
Selections *sel = self->paused_rendering.expires_at ? &self->paused_rendering.selections : &self->selections;
for (size_t i = 0; i < sel->count; i++) apply_selection(self, address, sel->items + i, 1);
sel->last_rendered_count = sel->count;
sel = self->paused_rendering.expires_at ? &self->paused_rendering.url_ranges : &self->url_ranges;
for (size_t i = 0; i < sel->count; i++) {
Selection *s = sel->items + i;
if (OPT(underline_hyperlinks) == UNDERLINE_NEVER && s->is_hyperlink) continue;
apply_selection(self, address, s, 2);
}
self->url_ranges.last_rendered_count = self->url_ranges.count;
sel->last_rendered_count = sel->count;
}
static index_type

View file

@ -157,6 +157,7 @@ typedef struct {
bool inverted, cell_data_updated;
unsigned int scrolled_by;
LineBuf *linebuf;
Selections selections, url_ranges;
} paused_rendering;
} Screen;

View file

@ -409,18 +409,22 @@ cell_prepare_to_render(ssize_t vao_idx, Screen *screen, GLfloat xstart, GLfloat
screen->last_rendered.cursor_y = cursor->y;
}
#define update_selection_data \
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) {
update_selection_data;
}
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;
update_selection_data;
}
if (grman_update_layers(screen->grman, screen->scrolled_by, xstart, ystart, dx, dy, screen->columns, screen->lines, screen->cell_size)) {
@ -428,6 +432,8 @@ cell_prepare_to_render(ssize_t vao_idx, Screen *screen, GLfloat xstart, GLfloat
}
screen->last_rendered.scrolled_by = screen->scrolled_by;
}
#undef update_selection_data
#undef update_cell_data
screen->last_rendered.columns = screen->columns;
screen->last_rendered.lines = screen->lines;
return changed;