Skip to content

Commit

Permalink
Reduce data sent to GPU per draw by 30%
Browse files Browse the repository at this point in the history
Split up the Cell structure into a CPUCell and a GPUCell. Only the
GPUCell part needs to be sent to the GPU. Should make kitty use even
less system resources and make a performance difference on systems where
the GPU bandwidth is constrained.

Also allows adding more CPU only data in the future without affecting
GPU bandwidth. For example, hyperlinks or more combining characters.
  • Loading branch information
kovidgoyal committed May 27, 2018
1 parent c875661 commit 8dea5b3
Show file tree
Hide file tree
Showing 13 changed files with 256 additions and 212 deletions.
2 changes: 1 addition & 1 deletion kitty/core_text.m
Expand Up @@ -178,7 +178,7 @@
}

PyObject*
create_fallback_face(PyObject *base_face, Cell* cell, bool UNUSED bold, bool UNUSED italic, bool emoji_presentation, FONTS_DATA_HANDLE fg UNUSED) {
create_fallback_face(PyObject *base_face, CPUCell* cell, bool UNUSED bold, bool UNUSED italic, bool emoji_presentation, FONTS_DATA_HANDLE fg UNUSED) {
CTFace *self = (CTFace*)base_face;
CTFontRef new_font;
if (emoji_presentation) new_font = CTFontCreateWithName((CFStringRef)@"AppleColorEmoji", self->scaled_point_sz, NULL);
Expand Down
4 changes: 2 additions & 2 deletions kitty/cursor.c
Expand Up @@ -136,7 +136,7 @@ END_ALLOW_CASE_RANGE
}

void
apply_sgr_to_cells(Cell *first_cell, unsigned int cell_count, unsigned int *params, unsigned int count) {
apply_sgr_to_cells(GPUCell *first_cell, unsigned int cell_count, unsigned int *params, unsigned int count) {
#define RANGE for(unsigned c = 0; c < cell_count; c++, cell++)
#define SET(shift) RANGE { cell->attrs |= (1 << shift); } break;
#define RESET(shift) RANGE { cell->attrs &= ~(1 << shift); } break;
Expand All @@ -148,7 +148,7 @@ apply_sgr_to_cells(Cell *first_cell, unsigned int cell_count, unsigned int *para
unsigned int i = 0, attr;
if (!count) { params[0] = 0; count = 1; }
while (i < count) {
Cell *cell = first_cell;
GPUCell *cell = first_cell;
attr = params[i++];
switch(attr) {
case 0:
Expand Down
28 changes: 17 additions & 11 deletions kitty/data-types.h
Expand Up @@ -80,7 +80,7 @@ typedef enum MouseShapes { BEAM, HAND, ARROW } MouseShape;
(c)->reverse = (a >> REVERSE_SHIFT) & 1; (c)->strikethrough = (a >> STRIKE_SHIFT) & 1; (c)->dim = (a >> DIM_SHIFT) & 1;

#define COPY_CELL(src, s, dest, d) \
(dest)->cells[d] = (src)->cells[s];
(dest)->cpu_cells[d] = (src)->cpu_cells[s]; (dest)->gpu_cells[d] = (src)->gpu_cells[s];

#define COPY_SELF_CELL(s, d) COPY_CELL(self, s, self, d)

Expand Down Expand Up @@ -140,15 +140,19 @@ typedef struct {
color_type fg, bg, decoration_fg;
sprite_index sprite_x, sprite_y, sprite_z;
attrs_type attrs;
// The following are only needed on the CPU, not the GPU
} GPUCell;

typedef struct {
char_type ch;
combining_type cc_idx[2];
} Cell;
} CPUCell;


typedef struct {
PyObject_HEAD

Cell *cells;
GPUCell *gpu_cells;
CPUCell *cpu_cells;
index_type xnum, ynum;
bool continued, needs_free, has_dirty_text;
} Line;
Expand All @@ -157,14 +161,16 @@ typedef struct {
typedef struct {
PyObject_HEAD

Cell *buf;
GPUCell *gpu_cell_buf;
CPUCell *cpu_cell_buf;
index_type xnum, ynum, *line_map, *scratch;
line_attrs_type *line_attrs;
Line *line;
} LineBuf;

typedef struct {
Cell *cells;
GPUCell *gpu_cells;
CPUCell *cpu_cells;
line_attrs_type *line_attrs;
} HistoryBufSegment;

Expand Down Expand Up @@ -226,10 +232,10 @@ typedef struct {FONTS_DATA_HEAD} *FONTS_DATA_HANDLE;
for(index_type __i__ = (at); __i__ < (line)->xnum - (num); __i__++) { \
COPY_CELL(line, __i__ + (num), line, __i__) \
} \
if ((((line)->cells[(at)].attrs) & WIDTH_MASK) != 1) { \
(line)->cells[(at)].ch = BLANK_CHAR; \
(line)->cells[(at)].attrs = BLANK_CHAR ? 1 : 0; \
clear_sprite_position((line)->cells[(at)]); \
if ((((line)->gpu_cells[(at)].attrs) & WIDTH_MASK) != 1) { \
(line)->cpu_cells[(at)].ch = BLANK_CHAR; \
(line)->gpu_cells[(at)].attrs = BLANK_CHAR ? 1 : 0; \
clear_sprite_position((line)->gpu_cells[(at)]); \
}\
}

Expand Down Expand Up @@ -260,7 +266,7 @@ Cursor* cursor_copy(Cursor*);
void cursor_copy_to(Cursor *src, Cursor *dest);
void cursor_reset_display_attrs(Cursor*);
void cursor_from_sgr(Cursor *self, unsigned int *params, unsigned int count);
void apply_sgr_to_cells(Cell *first_cell, unsigned int cell_count, unsigned int *params, unsigned int count);
void apply_sgr_to_cells(GPUCell *first_cell, unsigned int cell_count, unsigned int *params, unsigned int count);
const char* cursor_as_sgr(Cursor*, Cursor*);

double monotonic();
Expand Down
2 changes: 1 addition & 1 deletion kitty/fontconfig.c
Expand Up @@ -194,7 +194,7 @@ specialize_font_descriptor(PyObject *base_descriptor, FONTS_DATA_HANDLE fg) {
}

PyObject*
create_fallback_face(PyObject UNUSED *base_face, Cell* cell, bool bold, bool italic, bool emoji_presentation, FONTS_DATA_HANDLE fg) {
create_fallback_face(PyObject UNUSED *base_face, CPUCell* cell, bool bold, bool italic, bool emoji_presentation, FONTS_DATA_HANDLE fg) {
PyObject *ans = NULL;
FcPattern *pat = FcPatternCreate();
if (pat == NULL) return PyErr_NoMemory();
Expand Down

0 comments on commit 8dea5b3

Please sign in to comment.