From 79d8c04b00b139e4b6032bb17cda2bf6987b3c57 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 9 Nov 2017 16:17:24 +0530 Subject: [PATCH] Hook up render_line --- kitty/history.c | 11 +++++++++++ kitty/lineops.h | 2 ++ kitty/screen.c | 27 +++++++++++++++++++++++++-- kitty/shaders.c | 6 +++--- kitty/state.h | 1 + 5 files changed, 42 insertions(+), 5 deletions(-) diff --git a/kitty/history.c b/kitty/history.c index 81e8275e0..5122f9f61 100644 --- a/kitty/history.c +++ b/kitty/history.c @@ -72,6 +72,7 @@ init_line(HistoryBuf *self, index_type num, Line *l) { // Initialize the line l, setting its pointer to the offsets for the line at index (buffer position) num l->cells = lineptr(self, num); l->continued = self->line_attrs[num] & CONTINUED_MASK; + l->has_dirty_text = self->line_attrs[num] & TEXT_DIRTY_MASK ? true : false; } void @@ -79,6 +80,16 @@ historybuf_init_line(HistoryBuf *self, index_type lnum, Line *l) { init_line(self, index_of(self, lnum), l); } +void +historybuf_mark_line_clean(HistoryBuf *self, index_type y) { + self->line_attrs[index_of(self, y)] &= ~TEXT_DIRTY_MASK; +} + +void +historybuf_mark_line_dirty(HistoryBuf *self, index_type y) { + self->line_attrs[index_of(self, y)] |= TEXT_DIRTY_MASK; +} + static inline index_type historybuf_push(HistoryBuf *self) { index_type idx = (self->start_of_data + self->count) % self->ynum; diff --git a/kitty/lineops.h b/kitty/lineops.h index f76f42000..309bcb88f 100644 --- a/kitty/lineops.h +++ b/kitty/lineops.h @@ -75,4 +75,6 @@ bool historybuf_resize(HistoryBuf *self, index_type lines); void historybuf_add_line(HistoryBuf *self, const Line *line); void historybuf_rewrap(HistoryBuf *self, HistoryBuf *other); void historybuf_init_line(HistoryBuf *self, index_type num, Line *l); +void historybuf_mark_line_clean(HistoryBuf *self, index_type y); +void historybuf_mark_line_dirty(HistoryBuf *self, index_type y); void historybuf_refresh_sprite_positions(HistoryBuf *self); diff --git a/kitty/screen.c b/kitty/screen.c index e4e67b866..7316a6cc5 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -1162,17 +1162,28 @@ screen_reset_dirty(Screen *self) { void screen_update_cell_data(Screen *self, void *address, size_t UNUSED sz) { unsigned int history_line_added_count = self->history_line_added_count; + index_type lnum; bool selection_must_be_cleared = self->is_dirty ? true : false; if (self->scrolled_by) self->scrolled_by = MIN(self->scrolled_by + history_line_added_count, self->historybuf->count); screen_reset_dirty(self); self->scroll_changed = false; for (index_type y = 0; y < MIN(self->lines, self->scrolled_by); y++) { - historybuf_init_line(self->historybuf, self->scrolled_by - 1 - y, self->historybuf->line); + lnum = self->scrolled_by - 1 - y; + historybuf_init_line(self->historybuf, lnum, self->historybuf->line); update_line_data(self->historybuf->line, y, address); + if (self->historybuf->line->has_dirty_text) { + render_line(self->historybuf->line); + historybuf_mark_line_clean(self->historybuf, lnum); + } } for (index_type y = self->scrolled_by; y < self->lines; y++) { - linebuf_init_line(self->linebuf, y - self->scrolled_by); + lnum = y - self->scrolled_by; + linebuf_init_line(self->linebuf, lnum); update_line_data(self->linebuf->line, y, address); + if (self->linebuf->line->has_dirty_text) { + render_line(self->linebuf->line); + linebuf_mark_line_clean(self->linebuf, lnum); + } } if (selection_must_be_cleared) { self->selection = EMPTY_SELECTION; self->url_range = EMPTY_SELECTION; @@ -1259,6 +1270,17 @@ screen_url_range(Screen *self, uint32_t *data) { #define WRAP1E(name, defval, ...) static PyObject* name(Screen *self, PyObject *args) { unsigned int v=defval; if(!PyArg_ParseTuple(args, "|I", &v)) return NULL; screen_##name(self, v, __VA_ARGS__); Py_RETURN_NONE; } #define WRAP2(name, defval1, defval2) static PyObject* name(Screen *self, PyObject *args) { unsigned int a=defval1, b=defval2; if(!PyArg_ParseTuple(args, "|II", &a, &b)) return NULL; screen_##name(self, a, b); Py_RETURN_NONE; } +static PyObject* +refresh_sprite_positions(Screen *self) { + self->is_dirty = true; + for (index_type i = 0; i < self->lines; i++) { + linebuf_mark_line_dirty(self->main_linebuf, i); + linebuf_mark_line_dirty(self->alt_linebuf, i); + } + for (index_type i = 0; i < self->historybuf->count; i++) historybuf_mark_line_dirty(self->historybuf, i); + Py_RETURN_NONE; +} + static PyObject* screen_wcswidth(Screen UNUSED *self, PyObject *str) { if (PyUnicode_READY(str) != 0) return NULL; @@ -1576,6 +1598,7 @@ static PyMethodDef methods[] = { MND(cursor_forward, METH_VARARGS) {"wcswidth", (PyCFunction)screen_wcswidth, METH_O, ""}, {"index", (PyCFunction)xxx_index, METH_VARARGS, ""}, + MND(refresh_sprite_positions, METH_O) MND(tab, METH_NOARGS) MND(backspace, METH_NOARGS) MND(linefeed, METH_NOARGS) diff --git a/kitty/shaders.c b/kitty/shaders.c index 777ef4b20..974bf8f56 100644 --- a/kitty/shaders.c +++ b/kitty/shaders.c @@ -236,6 +236,9 @@ cell_prepare_to_render(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen, GLfloa size_t sz; CELL_BUFFERS; void *address; + + ensure_sprite_map(); + if (screen->scroll_changed || screen->is_dirty) { sz = sizeof(Cell) * screen->lines * screen->columns; address = alloc_and_map_vao_buffer(vao_idx, sz, cell_data_buffer, GL_STREAM_DRAW, GL_WRITE_ONLY); @@ -259,9 +262,6 @@ cell_prepare_to_render(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen, GLfloa cell_update_uniform_block(vao_idx, screen, uniform_buffer, xstart, ystart, dx, dy, cursor); - ensure_sprite_map(); - /* render_dirty_sprites(render_and_send_dirty_sprites); */ - bind_vao_uniform_buffer(vao_idx, uniform_buffer, cell_program_layouts[CELL_PROGRAM].render_data.index); bind_vertex_array(vao_idx); } diff --git a/kitty/state.h b/kitty/state.h index bff465fe1..6a9ea7b7c 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -105,3 +105,4 @@ void update_viewport_size(int, int); void free_texture(uint32_t*); void send_image_to_gpu(uint32_t*, const void*, int32_t, int32_t, bool, bool); void send_sprite_to_gpu(unsigned int, unsigned int, unsigned int, uint8_t*); +void render_line(Line *line);