Skip to content

Commit 8dea5b3

Browse files
committed
Reduce data sent to GPU per draw by 30%
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.
1 parent c875661 commit 8dea5b3

File tree

13 files changed

+256
-212
lines changed

13 files changed

+256
-212
lines changed

kitty/core_text.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@
178178
}
179179

180180
PyObject*
181-
create_fallback_face(PyObject *base_face, Cell* cell, bool UNUSED bold, bool UNUSED italic, bool emoji_presentation, FONTS_DATA_HANDLE fg UNUSED) {
181+
create_fallback_face(PyObject *base_face, CPUCell* cell, bool UNUSED bold, bool UNUSED italic, bool emoji_presentation, FONTS_DATA_HANDLE fg UNUSED) {
182182
CTFace *self = (CTFace*)base_face;
183183
CTFontRef new_font;
184184
if (emoji_presentation) new_font = CTFontCreateWithName((CFStringRef)@"AppleColorEmoji", self->scaled_point_sz, NULL);

kitty/cursor.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ END_ALLOW_CASE_RANGE
136136
}
137137

138138
void
139-
apply_sgr_to_cells(Cell *first_cell, unsigned int cell_count, unsigned int *params, unsigned int count) {
139+
apply_sgr_to_cells(GPUCell *first_cell, unsigned int cell_count, unsigned int *params, unsigned int count) {
140140
#define RANGE for(unsigned c = 0; c < cell_count; c++, cell++)
141141
#define SET(shift) RANGE { cell->attrs |= (1 << shift); } break;
142142
#define RESET(shift) RANGE { cell->attrs &= ~(1 << shift); } break;
@@ -148,7 +148,7 @@ apply_sgr_to_cells(Cell *first_cell, unsigned int cell_count, unsigned int *para
148148
unsigned int i = 0, attr;
149149
if (!count) { params[0] = 0; count = 1; }
150150
while (i < count) {
151-
Cell *cell = first_cell;
151+
GPUCell *cell = first_cell;
152152
attr = params[i++];
153153
switch(attr) {
154154
case 0:

kitty/data-types.h

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ typedef enum MouseShapes { BEAM, HAND, ARROW } MouseShape;
8080
(c)->reverse = (a >> REVERSE_SHIFT) & 1; (c)->strikethrough = (a >> STRIKE_SHIFT) & 1; (c)->dim = (a >> DIM_SHIFT) & 1;
8181

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

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

@@ -140,15 +140,19 @@ typedef struct {
140140
color_type fg, bg, decoration_fg;
141141
sprite_index sprite_x, sprite_y, sprite_z;
142142
attrs_type attrs;
143-
// The following are only needed on the CPU, not the GPU
143+
} GPUCell;
144+
145+
typedef struct {
144146
char_type ch;
145147
combining_type cc_idx[2];
146-
} Cell;
148+
} CPUCell;
149+
147150

148151
typedef struct {
149152
PyObject_HEAD
150153

151-
Cell *cells;
154+
GPUCell *gpu_cells;
155+
CPUCell *cpu_cells;
152156
index_type xnum, ynum;
153157
bool continued, needs_free, has_dirty_text;
154158
} Line;
@@ -157,14 +161,16 @@ typedef struct {
157161
typedef struct {
158162
PyObject_HEAD
159163

160-
Cell *buf;
164+
GPUCell *gpu_cell_buf;
165+
CPUCell *cpu_cell_buf;
161166
index_type xnum, ynum, *line_map, *scratch;
162167
line_attrs_type *line_attrs;
163168
Line *line;
164169
} LineBuf;
165170

166171
typedef struct {
167-
Cell *cells;
172+
GPUCell *gpu_cells;
173+
CPUCell *cpu_cells;
168174
line_attrs_type *line_attrs;
169175
} HistoryBufSegment;
170176

@@ -226,10 +232,10 @@ typedef struct {FONTS_DATA_HEAD} *FONTS_DATA_HANDLE;
226232
for(index_type __i__ = (at); __i__ < (line)->xnum - (num); __i__++) { \
227233
COPY_CELL(line, __i__ + (num), line, __i__) \
228234
} \
229-
if ((((line)->cells[(at)].attrs) & WIDTH_MASK) != 1) { \
230-
(line)->cells[(at)].ch = BLANK_CHAR; \
231-
(line)->cells[(at)].attrs = BLANK_CHAR ? 1 : 0; \
232-
clear_sprite_position((line)->cells[(at)]); \
235+
if ((((line)->gpu_cells[(at)].attrs) & WIDTH_MASK) != 1) { \
236+
(line)->cpu_cells[(at)].ch = BLANK_CHAR; \
237+
(line)->gpu_cells[(at)].attrs = BLANK_CHAR ? 1 : 0; \
238+
clear_sprite_position((line)->gpu_cells[(at)]); \
233239
}\
234240
}
235241

@@ -260,7 +266,7 @@ Cursor* cursor_copy(Cursor*);
260266
void cursor_copy_to(Cursor *src, Cursor *dest);
261267
void cursor_reset_display_attrs(Cursor*);
262268
void cursor_from_sgr(Cursor *self, unsigned int *params, unsigned int count);
263-
void apply_sgr_to_cells(Cell *first_cell, unsigned int cell_count, unsigned int *params, unsigned int count);
269+
void apply_sgr_to_cells(GPUCell *first_cell, unsigned int cell_count, unsigned int *params, unsigned int count);
264270
const char* cursor_as_sgr(Cursor*, Cursor*);
265271

266272
double monotonic();

kitty/fontconfig.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ specialize_font_descriptor(PyObject *base_descriptor, FONTS_DATA_HANDLE fg) {
194194
}
195195

196196
PyObject*
197-
create_fallback_face(PyObject UNUSED *base_face, Cell* cell, bool bold, bool italic, bool emoji_presentation, FONTS_DATA_HANDLE fg) {
197+
create_fallback_face(PyObject UNUSED *base_face, CPUCell* cell, bool bold, bool italic, bool emoji_presentation, FONTS_DATA_HANDLE fg) {
198198
PyObject *ans = NULL;
199199
FcPattern *pat = FcPatternCreate();
200200
if (pat == NULL) return PyErr_NoMemory();

0 commit comments

Comments
 (0)