diff --git a/kitty/boss.py b/kitty/boss.py index d3d21141e..2674cc201 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -459,7 +459,7 @@ class Boss(Thread): if isosx: cocoa_update_title(self.glfw_window_title) with self.sprites: - self.sprites.render_dirty_cells() + self.sprites.render_dirty_sprites() tab.render() render_data = { window: diff --git a/kitty/shaders.py b/kitty/shaders.py index 0d3559ade..bbbf54ddd 100644 --- a/kitty/shaders.py +++ b/kitty/shaders.py @@ -153,8 +153,12 @@ class Sprites: # {{{ ans = second if is_second else first return ans or render_cell()[0] - def render_dirty_cells(self): - render_dirty_sprites(self.render_cell, self.send_to_gpu) + def render_dirty_sprites(self): + ret = render_dirty_sprites() + if ret: + for text, bold, italic, is_second, x, y, z in ret: + cell = self.render_cell(text, bold, italic, is_second) + self.send_to_gpu(x, y, z, cell) def send_to_gpu(self, x, y, z, buf): xnum, ynum, znum = sprite_map_current_layout() diff --git a/kitty/sprites.c b/kitty/sprites.c index 18e8165fa..d8ac94a95 100644 --- a/kitty/sprites.c +++ b/kitty/sprites.c @@ -182,34 +182,30 @@ update_cell_range_data(ScreenModes *modes, Line *line, unsigned int xstart, unsi } PyObject* -render_dirty_sprites(PyObject UNUSED *s_, PyObject *args) { +render_dirty_sprites(PyObject UNUSED *s_) { #define render_dirty_cells_doc "Render all cells that are marked as dirty" - PyObject *render_cell, *send_to_gpu; - - if (!PyArg_ParseTuple(args, "OO", &render_cell, &send_to_gpu)) return NULL; - if (!sprite_map.dirty) { Py_RETURN_NONE; } + PyObject *ans = PyList_New(0); + if (ans == NULL) return NULL; for (size_t i = 0; i < sizeof(sprite_map.cache)/sizeof(sprite_map.cache[0]); i++) { SpritePosition *sp = &(sprite_map.cache[i]); - while (sp) { + do { if (sp->filled && !sp->rendered) { PyObject *text = line_text_at(sp->ch & CHAR_MASK, sp->cc); if (text == NULL) return NULL; char_type attrs = sp->ch >> ATTRS_SHIFT; bool bold = (attrs >> BOLD_SHIFT) & 1, italic = (attrs >> ITALIC_SHIFT) & 1; - PyObject *rcell = PyObject_CallFunctionObjArgs(render_cell, text, bold ? Py_True : Py_False, italic ? Py_True : Py_False, sp->is_second ? Py_True : Py_False, NULL); + PyObject *x = Py_BuildValue("OOOOHHH", text, bold ? Py_True : Py_False, italic ? Py_True : Py_False, sp->is_second ? Py_True : Py_False, sp->x, sp->y, sp->z); Py_CLEAR(text); - if (rcell == NULL) return NULL; - PyObject *ret = PyObject_CallFunction(send_to_gpu, "IIIO", sp->x, sp->y, sp->z, rcell); - Py_CLEAR(rcell); - if (ret == NULL) return NULL; - Py_CLEAR(ret); + if (x == NULL) { Py_CLEAR(ans); return NULL; } + if (PyList_Append(ans, x) != 0) { Py_CLEAR(ans); return NULL; } + Py_CLEAR(x); sp->rendered = true; } sp = sp->next; - } + } while(sp); } sprite_map.dirty = false; - Py_RETURN_NONE; + return ans; } diff --git a/kitty/sprites.h b/kitty/sprites.h index e68a6851f..ffae2e5a6 100644 --- a/kitty/sprites.h +++ b/kitty/sprites.h @@ -26,7 +26,7 @@ PyObject* sprite_map_increment(); SpritePosition* sprite_map_position_for(char_type ch, combining_type cc, bool is_second, int *error); PyObject* sprite_position_for(PyObject UNUSED *self, PyObject *args); bool update_cell_range_data(ScreenModes *modes, Line *line, unsigned int xstart, unsigned int xmax, unsigned int *data); -PyObject* render_dirty_sprites(PyObject UNUSED *self, PyObject *args); +PyObject* render_dirty_sprites(PyObject UNUSED *self); #define SPRITE_FUNC_WRAPPERS \ {"sprite_map_set_limits", (PyCFunction)sprite_map_set_limits, METH_VARARGS, ""}, \ @@ -35,5 +35,5 @@ PyObject* render_dirty_sprites(PyObject UNUSED *self, PyObject *args); {"sprite_map_free", (PyCFunction)sprite_map_free, METH_NOARGS, ""}, \ {"sprite_map_increment", (PyCFunction)sprite_map_increment, METH_NOARGS, ""}, \ {"sprite_position_for", (PyCFunction)sprite_position_for, METH_VARARGS, ""}, \ - {"render_dirty_sprites", (PyCFunction)render_dirty_sprites, METH_VARARGS, ""}, \ + {"render_dirty_sprites", (PyCFunction)render_dirty_sprites, METH_NOARGS, ""}, \ diff --git a/kitty/tabs.py b/kitty/tabs.py index 8875a99d3..296d27e0c 100644 --- a/kitty/tabs.py +++ b/kitty/tabs.py @@ -302,7 +302,7 @@ class TabBar: def render(self, cell_program, sprites): ' Must be called in the GUI thread ' if self.render_buf is not None: - sprites.render_dirty_cells() + sprites.render_dirty_sprites() if self.vao_id is None: self.vao_id = cell_program.create_sprite_map() if self.dirty: