Skip to content

Commit

Permalink
Optimize implementation of clear screen escape code
Browse files Browse the repository at this point in the history
  • Loading branch information
kovidgoyal committed Jan 18, 2024
1 parent fa0ffaa commit 87636e9
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 10 deletions.
2 changes: 2 additions & 0 deletions kitty/data-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,8 @@ cursor_to_attrs(const Cursor *c, const uint16_t width) {
return ans;
}

#define cursor_as_gpu_cell(cursor) {.attrs=cursor_to_attrs(cursor, 0), .fg=(cursor->fg & COL_MASK), .bg=(cursor->bg & COL_MASK), .decoration_fg=cursor->decoration_fg & COL_MASK}

static inline void
attrs_to_cursor(const CellAttrs attrs, Cursor *c) {
c->decoration = attrs.decoration; c->bold = attrs.bold; c->italic = attrs.italic;
Expand Down
16 changes: 16 additions & 0 deletions kitty/line-buf.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,22 @@ linebuf_init_line(LineBuf *self, index_type idx) {
init_line(self, self->line, self->line_map[idx]);
}

void
linebuf_clear_lines(LineBuf *self, const Cursor *cursor, index_type start, index_type end) {
GPUCell *first_gpu_line = gpu_lineptr(self, start);
GPUCell gc = cursor_as_gpu_cell(cursor);
for (index_type i = 0; i < self->xnum; i++) memcpy(first_gpu_line + i, &gc, sizeof(gc));
const size_t cpu_stride = sizeof(self->cpu_cell_buf[0]) * self->xnum;
memset(cpu_lineptr(self, start), 0, cpu_stride);
const size_t gpu_stride = sizeof(self->gpu_cell_buf[0]) * self->xnum;
linebuf_clear_attrs_and_dirty(self, start);
for (index_type i = start + 1; i < end; i++) {
memset(cpu_lineptr(self, i), 0, cpu_stride);
memcpy(gpu_lineptr(self, i), first_gpu_line, gpu_stride);
linebuf_clear_attrs_and_dirty(self, i);
}
}

static PyObject*
line(LineBuf *self, PyObject *y) {
#define line_doc "Return the specified line as a Line object. Note the Line Object is a live view into the underlying buffer. And only a single line object can be used at a time."
Expand Down
4 changes: 2 additions & 2 deletions kitty/line.c
Original file line number Diff line number Diff line change
Expand Up @@ -539,8 +539,8 @@ clear_text(Line* self, PyObject *args) {
}

void
line_apply_cursor(Line *self, Cursor *cursor, unsigned int at, unsigned int num, bool clear_char) {
GPUCell gc = {.attrs=cursor_to_attrs(cursor, 0), .fg=(cursor->fg & COL_MASK), .bg=(cursor->bg & COL_MASK), .decoration_fg=cursor->decoration_fg & COL_MASK};
line_apply_cursor(Line *self, const Cursor *cursor, unsigned int at, unsigned int num, bool clear_char) {
GPUCell gc = cursor_as_gpu_cell(cursor);
if (clear_char) {
for (index_type i = at; i < self->xnum && i < at + num; i++) {
memset(self->cpu_cells + i, 0, sizeof(self->cpu_cells[0]));
Expand Down
3 changes: 2 additions & 1 deletion kitty/lineops.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ line_is_empty(const Line *line) {

typedef Line*(get_line_func)(void *, int);
void line_clear_text(Line *self, unsigned int at, unsigned int num, char_type ch);
void line_apply_cursor(Line *self, Cursor *cursor, unsigned int at, unsigned int num, bool clear_char);
void line_apply_cursor(Line *self, const Cursor *cursor, unsigned int at, unsigned int num, bool clear_char);
char_type line_get_char(Line *self, index_type at);
void line_set_char(Line *, unsigned int , uint32_t , unsigned int , Cursor *, hyperlink_id_type);
void line_right_shift(Line *, unsigned int , unsigned int );
Expand All @@ -103,6 +103,7 @@ PyObject* line_as_unicode(Line *, bool);
void linebuf_init_line(LineBuf *, index_type);
void linebuf_init_cells(LineBuf *lb, index_type ynum, CPUCell **c, GPUCell **g);
void linebuf_clear(LineBuf *, char_type ch);
void linebuf_clear_lines(LineBuf *self, const Cursor *cursor, index_type start, index_type end);
void linebuf_index(LineBuf* self, index_type top, index_type bottom);
void linebuf_reverse_index(LineBuf *self, index_type top, index_type bottom);
void linebuf_clear_line(LineBuf *self, index_type y, bool clear_attrs);
Expand Down
12 changes: 5 additions & 7 deletions kitty/screen.c
Original file line number Diff line number Diff line change
Expand Up @@ -1866,16 +1866,14 @@ screen_erase_in_display(Screen *self, unsigned int how, bool private) {
}
if (b > a) {
if (how != 3) screen_dirty_line_graphics(self, a, b, self->linebuf == self->main_linebuf);
for (unsigned int i=a; i < b; i++) {
linebuf_init_line(self->linebuf, i);
if (private) {
if (private) {
for (unsigned int i=a; i < b; i++) {
linebuf_init_line(self->linebuf, i);
line_clear_text(self->linebuf->line, 0, self->columns, BLANK_CHAR);
linebuf_set_last_char_as_continuation(self->linebuf, i, false);
} else {
line_apply_cursor(self->linebuf->line, self->cursor, 0, self->columns, true);
linebuf_clear_attrs_and_dirty(self->linebuf, i);
}
linebuf_clear_attrs_and_dirty(self->linebuf, i);
}
} else linebuf_clear_lines(self->linebuf, self->cursor, a, b);
self->is_dirty = true;
clear_selection(&self->selections);
}
Expand Down

0 comments on commit 87636e9

Please sign in to comment.