Make the TextCache object available in the Screen, LineBuf and Line objects

This commit is contained in:
Kovid Goyal
2024-07-14 14:26:55 +05:30
parent 05120061cc
commit 5a2440eb97
8 changed files with 43 additions and 22 deletions

View File

@@ -114,7 +114,7 @@ pagerhist_clear(HistoryBuf *self) {
}
static HistoryBuf*
create_historybuf(PyTypeObject *type, unsigned int xnum, unsigned int ynum, unsigned int pagerhist_sz) {
create_historybuf(PyTypeObject *type, unsigned int xnum, unsigned int ynum, unsigned int pagerhist_sz, TextCache *tc) {
if (xnum == 0 || ynum == 0) {
PyErr_SetString(PyExc_ValueError, "Cannot create an empty history buffer");
return NULL;
@@ -125,7 +125,8 @@ create_historybuf(PyTypeObject *type, unsigned int xnum, unsigned int ynum, unsi
self->ynum = ynum;
self->num_segments = 0;
add_segment(self);
self->line = alloc_line();
self->text_cache = tc_incref(tc);
self->line = alloc_line(self->text_cache);
self->line->xnum = xnum;
self->pagerhist = alloc_pagerhist(pagerhist_sz);
}
@@ -136,7 +137,10 @@ static PyObject *
new_history_object(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
unsigned int xnum = 1, ynum = 1, pagerhist_sz = 0;
if (!PyArg_ParseTuple(args, "II|I", &ynum, &xnum, &pagerhist_sz)) return NULL;
HistoryBuf *ans = create_historybuf(type, xnum, ynum, pagerhist_sz);
TextCache *tc = tc_alloc();
if (!tc) return PyErr_NoMemory();
HistoryBuf *ans = create_historybuf(type, xnum, ynum, pagerhist_sz, tc);
tc_decref(tc);
return (PyObject*)ans;
}
@@ -146,6 +150,7 @@ dealloc(HistoryBuf* self) {
for (size_t i = 0; i < self->num_segments; i++) free_segment(self->segments + i);
free(self->segments);
free_pagerhist(self);
tc_decref(self->text_cache);
Py_TYPE(self)->tp_free((PyObject*)self);
}
@@ -574,8 +579,8 @@ PyTypeObject HistoryBuf_Type = {
INIT_TYPE(HistoryBuf)
HistoryBuf *alloc_historybuf(unsigned int lines, unsigned int columns, unsigned int pagerhist_sz) {
return create_historybuf(&HistoryBuf_Type, columns, lines, pagerhist_sz);
HistoryBuf *alloc_historybuf(unsigned int lines, unsigned int columns, unsigned int pagerhist_sz, TextCache *tc) {
return create_historybuf(&HistoryBuf_Type, columns, lines, pagerhist_sz, tc);
}
// }}}

View File

@@ -16,8 +16,9 @@ typedef struct {
HistoryBufSegment *segments;
PagerHistoryBuf *pagerhist;
Line *line;
TextCache *text_cache;
index_type start_of_data, count;
} HistoryBuf;
HistoryBuf* alloc_historybuf(unsigned int, unsigned int, unsigned int);
HistoryBuf* alloc_historybuf(unsigned int, unsigned int, unsigned int, TextCache *tc);

View File

@@ -71,7 +71,7 @@ clear(LineBuf *self, PyObject *a UNUSED) {
}
LineBuf *
alloc_linebuf_(PyTypeObject *cls, unsigned int lines, unsigned int columns) {
alloc_linebuf_(PyTypeObject *cls, unsigned int lines, unsigned int columns, TextCache *text_cache) {
if (columns > 5000 || lines > 50000) {
PyErr_SetString(PyExc_ValueError, "Number of rows or columns is too large.");
return NULL;
@@ -92,8 +92,9 @@ alloc_linebuf_(PyTypeObject *cls, unsigned int lines, unsigned int columns) {
self->gpu_cell_buf = (GPUCell*)(self->cpu_cell_buf + area);
self->line_map = (index_type*)(self->gpu_cell_buf + area);
self->scratch = self->line_map + lines;
self->text_cache = tc_incref(text_cache);
self->line = alloc_line(self->text_cache);
self->line_attrs = (LineAttrs*)(self->scratch + lines);
self->line = alloc_line();
self->line->xnum = columns;
for(index_type i = 0; i < lines; i++) {
self->line_map[i] = i;
@@ -108,11 +109,16 @@ new_linebuf_object(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
unsigned int xnum = 1, ynum = 1;
if (!PyArg_ParseTuple(args, "II", &ynum, &xnum)) return NULL;
return (PyObject*)alloc_linebuf_(type, ynum, xnum);
TextCache *tc = tc_alloc();
if (!tc) return PyErr_NoMemory();
PyObject *ans = (PyObject*)alloc_linebuf_(type, ynum, xnum, tc);
tc_decref(tc);
return ans;
}
static void
dealloc(LineBuf* self) {
self->text_cache = tc_decref(self->text_cache);
PyMem_Free(self->cpu_cell_buf);
Py_CLEAR(self->line);
Py_TYPE(self)->tp_free((PyObject*)self);
@@ -249,7 +255,7 @@ allocate_line_storage(Line *line, bool initialize) {
static PyObject*
create_line_copy_inner(LineBuf* self, index_type y) {
Line src, *line;
line = alloc_line();
line = alloc_line(self->text_cache);
if (line == NULL) return PyErr_NoMemory();
src.xnum = self->xnum; line->xnum = self->xnum;
if (!allocate_line_storage(line, 0)) { Py_CLEAR(line); return PyErr_NoMemory(); }
@@ -631,4 +637,4 @@ rewrap(LineBuf *self, PyObject *args) {
LineBuf *
alloc_linebuf(unsigned int lines, unsigned int columns) { return alloc_linebuf_(&LineBuf_Type, lines, columns); }
alloc_linebuf(unsigned int lines, unsigned int columns, TextCache *tc) { return alloc_linebuf_(&LineBuf_Type, lines, columns, tc); }

View File

@@ -8,6 +8,7 @@
#pragma once
#include "line.h"
#include "text-cache.h"
typedef struct {
PyObject_HEAD
@@ -17,7 +18,8 @@ typedef struct {
index_type xnum, ynum, *line_map, *scratch;
LineAttrs *line_attrs;
Line *line;
TextCache *text_cache;
} LineBuf;
LineBuf* alloc_linebuf(unsigned int, unsigned int);
LineBuf* alloc_linebuf(unsigned int, unsigned int, TextCache*);

View File

@@ -19,6 +19,7 @@ dealloc(Line* self) {
PyMem_Free(self->cpu_cells);
PyMem_Free(self->gpu_cells);
}
tc_decref(self->text_cache);
Py_TYPE(self)->tp_free((PyObject*)self);
}
@@ -972,8 +973,10 @@ PyTypeObject Line_Type = {
.tp_methods = methods,
};
Line *alloc_line(void) {
return (Line*)Line_Type.tp_alloc(&Line_Type, 0);
Line *alloc_line(TextCache *tc) {
Line *ans = (Line*)Line_Type.tp_alloc(&Line_Type, 0);
if (ans) ans->text_cache = tc_incref(tc);
return ans;
}
RICHCMP(Line)

View File

@@ -7,7 +7,7 @@
#pragma once
#include "data-types.h"
#include "text-cache.h"
typedef struct {
PyObject_HEAD
@@ -17,6 +17,7 @@ typedef struct {
index_type xnum, ynum;
bool needs_free;
LineAttrs attrs;
TextCache *text_cache;
} Line;
Line* alloc_line(void);
Line* alloc_line(TextCache *text_cache);

View File

@@ -107,6 +107,7 @@ new_screen_object(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
}
self->vt_parser = alloc_vt_parser(window_id);
if (self->vt_parser == NULL) { Py_CLEAR(self); return PyErr_NoMemory(); }
self->text_cache = tc_alloc(); if (!self->text_cache) { Py_CLEAR(self); return PyErr_NoMemory(); }
self->reload_all_gpu_data = true;
self->cell_size.width = cell_width; self->cell_size.height = cell_height;
self->columns = columns; self->lines = lines;
@@ -125,9 +126,9 @@ new_screen_object(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
self->test_child = test_child; Py_INCREF(test_child);
self->cursor = alloc_cursor();
self->color_profile = alloc_color_profile();
self->main_linebuf = alloc_linebuf(lines, columns); self->alt_linebuf = alloc_linebuf(lines, columns);
self->main_linebuf = alloc_linebuf(lines, columns, self->text_cache); self->alt_linebuf = alloc_linebuf(lines, columns, self->text_cache);
self->linebuf = self->main_linebuf;
self->historybuf = alloc_historybuf(MAX(scrollback, lines), columns, OPT(scrollback_pager_history_size));
self->historybuf = alloc_historybuf(MAX(scrollback, lines), columns, OPT(scrollback_pager_history_size), self->text_cache);
self->main_grman = grman_alloc(false);
self->alt_grman = grman_alloc(false);
self->active_hyperlink_id = 0;
@@ -214,7 +215,7 @@ screen_dirty_sprite_positions(Screen *self) {
static HistoryBuf*
realloc_hb(HistoryBuf *old, unsigned int lines, unsigned int columns, ANSIBuf *as_ansi_buf) {
HistoryBuf *ans = alloc_historybuf(lines, columns, 0);
HistoryBuf *ans = alloc_historybuf(lines, columns, 0, old->text_cache);
if (ans == NULL) { PyErr_NoMemory(); return NULL; }
ans->pagerhist = old->pagerhist; old->pagerhist = NULL;
historybuf_rewrap(old, ans, as_ansi_buf);
@@ -232,7 +233,7 @@ typedef struct CursorTrack {
static LineBuf*
realloc_lb(LineBuf *old, unsigned int lines, unsigned int columns, index_type *nclb, index_type *ncla, HistoryBuf *hb, CursorTrack *a, CursorTrack *b, ANSIBuf *as_ansi_buf) {
LineBuf *ans = alloc_linebuf(lines, columns);
LineBuf *ans = alloc_linebuf(lines, columns, old->text_cache);
if (ans == NULL) { PyErr_NoMemory(); return NULL; }
a->temp.x = a->before.x; a->temp.y = a->before.y;
b->temp.x = b->before.x; b->temp.y = b->before.y;
@@ -398,7 +399,7 @@ screen_resize(Screen *self, unsigned int lines, unsigned int columns) {
RAII_PyObject(prompt_copy, NULL);
index_type num_of_prompt_lines = 0, num_of_prompt_lines_above_cursor = 0;
if (is_main) {
prompt_copy = (PyObject*)alloc_linebuf(self->lines, self->columns);
prompt_copy = (PyObject*)alloc_linebuf(self->lines, self->columns, self->text_cache);
num_of_prompt_lines = prevent_current_prompt_from_rewrapping(self, (LineBuf*)prompt_copy, &num_of_prompt_lines_above_cursor);
}
LineBuf *n = realloc_lb(self->main_linebuf, lines, columns, &num_content_lines_before, &num_content_lines_after, self->historybuf, &cursor, &main_saved_cursor, &self->as_ansi_buf);
@@ -500,6 +501,7 @@ static void
dealloc(Screen* self) {
pthread_mutex_destroy(&self->write_buf_lock);
free_vt_parser(self->vt_parser); self->vt_parser = NULL;
self->text_cache = tc_decref(self->text_cache);
Py_CLEAR(self->main_grman);
Py_CLEAR(self->alt_grman);
Py_CLEAR(self->last_reported_cwd);
@@ -2539,7 +2541,7 @@ screen_pause_rendering(Screen *self, bool pause, int for_in_ms) {
memcpy(&self->paused_rendering.color_profile, self->color_profile, sizeof(self->paused_rendering.color_profile));
if (!self->paused_rendering.linebuf || self->paused_rendering.linebuf->xnum != self->columns || self->paused_rendering.linebuf->ynum != self->lines) {
if (self->paused_rendering.linebuf) Py_CLEAR(self->paused_rendering.linebuf);
self->paused_rendering.linebuf = alloc_linebuf(self->lines, self->columns);
self->paused_rendering.linebuf = alloc_linebuf(self->lines, self->columns, self->text_cache);
if (!self->paused_rendering.linebuf) { PyErr_Clear(); self->paused_rendering.expires_at = 0; return false; }
}
for (index_type y = 0; y < self->lines; y++) {

View File

@@ -105,6 +105,7 @@ typedef struct {
Cursor *cursor;
Savepoint main_savepoint, alt_savepoint;
PyObject *callbacks, *test_child;
TextCache *text_cache;
LineBuf *linebuf, *main_linebuf, *alt_linebuf;
GraphicsManager *grman, *main_grman, *alt_grman;
HistoryBuf *historybuf;