Dont send the color table to the GPU on every frame
This commit is contained in:
@@ -4,7 +4,9 @@ uniform vec4 steps; // xstart, ystart, dx, dy
|
|||||||
uniform vec2 sprite_layout; // dx, dy
|
uniform vec2 sprite_layout; // dx, dy
|
||||||
uniform ivec2 color_indices; // which color to use as fg and which as bg
|
uniform ivec2 color_indices; // which color to use as fg and which as bg
|
||||||
uniform uvec4 default_colors; // The default colors
|
uniform uvec4 default_colors; // The default colors
|
||||||
uniform uint color_table[256]; // The color table
|
uniform ColorTable {
|
||||||
|
uint color_table[256]; // The color table
|
||||||
|
};
|
||||||
in uvec3 sprite_coords;
|
in uvec3 sprite_coords;
|
||||||
in uvec3 colors;
|
in uvec3 colors;
|
||||||
in float is_selected;
|
in float is_selected;
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ from .constants import (
|
|||||||
from .fast_data_types import (
|
from .fast_data_types import (
|
||||||
CURSOR_BEAM, CURSOR_BLOCK, CURSOR_UNDERLINE, DATA_CELL_SIZE, GL_BLEND,
|
CURSOR_BEAM, CURSOR_BLOCK, CURSOR_UNDERLINE, DATA_CELL_SIZE, GL_BLEND,
|
||||||
GL_FLOAT, GL_LINE_LOOP, GL_TRIANGLE_FAN, GL_UNSIGNED_INT, glDisable,
|
GL_FLOAT, GL_LINE_LOOP, GL_TRIANGLE_FAN, GL_UNSIGNED_INT, glDisable,
|
||||||
glDrawArrays, glDrawArraysInstanced, glEnable, glUniform1i, glUniform1uiv,
|
glDrawArrays, glDrawArraysInstanced, glEnable, glUniform1i, glUniform2f,
|
||||||
glUniform2f, glUniform2i, glUniform2ui, glUniform4f, glUniform4ui
|
glUniform2i, glUniform2ui, glUniform4f, glUniform4ui
|
||||||
)
|
)
|
||||||
from .rgb import to_color
|
from .rgb import to_color
|
||||||
from .shaders import ShaderProgram, load_shaders
|
from .shaders import ShaderProgram, load_shaders
|
||||||
@@ -35,6 +35,21 @@ class DynamicColor(Enum):
|
|||||||
|
|
||||||
class CellProgram(ShaderProgram):
|
class CellProgram(ShaderProgram):
|
||||||
|
|
||||||
|
def __init__(self, *args):
|
||||||
|
ShaderProgram.__init__(self, *args)
|
||||||
|
self.color_table_buf = None
|
||||||
|
|
||||||
|
def send_color_table(self, color_profile):
|
||||||
|
if color_profile.ubo is None:
|
||||||
|
color_profile.ubo = self.init_uniform_block('ColorTable', 'color_table')
|
||||||
|
ubo = color_profile.ubo
|
||||||
|
if self.color_table_buf is None:
|
||||||
|
self.color_table_buf = (GLuint * (ubo.size // sizeof(GLuint)))()
|
||||||
|
offset = ubo.offsets['color_table'] // sizeof(GLuint)
|
||||||
|
stride = ubo.size // (256 * sizeof(GLuint))
|
||||||
|
color_profile.copy_color_table(addressof(self.color_table_buf), offset, stride)
|
||||||
|
self.send_uniform_buffer_data(ubo, self.color_table_buf)
|
||||||
|
|
||||||
def create_sprite_map(self):
|
def create_sprite_map(self):
|
||||||
with self.array_object_creator() as add_attribute:
|
with self.array_object_creator() as add_attribute:
|
||||||
stride = DATA_CELL_SIZE * sizeof(GLuint)
|
stride = DATA_CELL_SIZE * sizeof(GLuint)
|
||||||
@@ -124,15 +139,17 @@ def calculate_gl_geometry(window_geometry, viewport_width, viewport_height, cell
|
|||||||
|
|
||||||
|
|
||||||
def render_cells(vao_id, sg, cell_program, sprites, color_profile, invert_colors=False):
|
def render_cells(vao_id, sg, cell_program, sprites, color_profile, invert_colors=False):
|
||||||
|
if color_profile.dirty:
|
||||||
|
cell_program.send_color_table(color_profile)
|
||||||
|
color_profile.dirty = False
|
||||||
ul = cell_program.uniform_location
|
ul = cell_program.uniform_location
|
||||||
glUniform2ui(ul('dimensions'), sg.xnum, sg.ynum)
|
glUniform2ui(ul('dimensions'), sg.xnum, sg.ynum)
|
||||||
glUniform4ui(ul('default_colors'), color_profile.default_fg, color_profile.default_bg, color_profile.highlight_fg, color_profile.highlight_bg)
|
glUniform4ui(ul('default_colors'), color_profile.default_fg, color_profile.default_bg, color_profile.highlight_fg, color_profile.highlight_bg)
|
||||||
glUniform1uiv(ul('color_table'), 256, color_profile.color_table_address())
|
|
||||||
glUniform2i(ul('color_indices'), 1 if invert_colors else 0, 0 if invert_colors else 1)
|
glUniform2i(ul('color_indices'), 1 if invert_colors else 0, 0 if invert_colors else 1)
|
||||||
glUniform4f(ul('steps'), sg.xstart, sg.ystart, sg.dx, sg.dy)
|
glUniform4f(ul('steps'), sg.xstart, sg.ystart, sg.dx, sg.dy)
|
||||||
glUniform1i(ul('sprites'), sprites.sampler_num)
|
glUniform1i(ul('sprites'), sprites.sampler_num)
|
||||||
glUniform2f(ul('sprite_layout'), *(sprites.layout))
|
glUniform2f(ul('sprite_layout'), *(sprites.layout))
|
||||||
with cell_program.bound_vertex_array(vao_id):
|
with cell_program.bound_vertex_array(vao_id), cell_program.bound_uniform_buffer(color_profile.ubo):
|
||||||
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, sg.xnum * sg.ynum)
|
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, sg.xnum * sg.ynum)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ new(PyTypeObject *type, PyObject UNUSED *args, PyObject UNUSED *kwds) {
|
|||||||
memcpy(self->color_table, FG_BG_256, sizeof(FG_BG_256));
|
memcpy(self->color_table, FG_BG_256, sizeof(FG_BG_256));
|
||||||
memcpy(self->orig_color_table, FG_BG_256, sizeof(FG_BG_256));
|
memcpy(self->orig_color_table, FG_BG_256, sizeof(FG_BG_256));
|
||||||
self->dirty = Py_True; Py_INCREF(Py_True);
|
self->dirty = Py_True; Py_INCREF(Py_True);
|
||||||
|
self->ubo = Py_None; Py_INCREF(Py_None);
|
||||||
}
|
}
|
||||||
return (PyObject*) self;
|
return (PyObject*) self;
|
||||||
}
|
}
|
||||||
@@ -68,6 +69,7 @@ new(PyTypeObject *type, PyObject UNUSED *args, PyObject UNUSED *kwds) {
|
|||||||
static void
|
static void
|
||||||
dealloc(ColorProfile* self) {
|
dealloc(ColorProfile* self) {
|
||||||
Py_DECREF(self->dirty);
|
Py_DECREF(self->dirty);
|
||||||
|
Py_DECREF(self->ubo);
|
||||||
Py_TYPE(self)->tp_free((PyObject*)self);
|
Py_TYPE(self)->tp_free((PyObject*)self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,6 +164,20 @@ set_configured_colors(ColorProfile *self, PyObject *args) {
|
|||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
copy_color_table(ColorProfile *self, PyObject *args) {
|
||||||
|
#define copy_color_table_doc "copy_color_table(address, offset, stride) -> copy the color table into the memory at address, using the specified offset and stride."
|
||||||
|
unsigned int offset, stride, i;
|
||||||
|
PyObject *ptr;
|
||||||
|
if (!PyArg_ParseTuple(args, "OII", &ptr, &offset, &stride)) return NULL;
|
||||||
|
color_type *buf = (color_type*)PyLong_AsVoidPtr(ptr);
|
||||||
|
stride = MAX(1, stride);
|
||||||
|
for (i = 0, buf = buf + offset; i < sizeof(self->color_table)/sizeof(self->color_table[0]); i++, buf += stride) {
|
||||||
|
*buf = self->color_table[i];
|
||||||
|
}
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
color_table_address(ColorProfile *self) {
|
color_table_address(ColorProfile *self) {
|
||||||
#define color_table_address_doc "Pointer address to start of color table"
|
#define color_table_address_doc "Pointer address to start of color table"
|
||||||
@@ -193,6 +209,7 @@ static PyGetSetDef getsetters[] = {
|
|||||||
|
|
||||||
static PyMemberDef members[] = {
|
static PyMemberDef members[] = {
|
||||||
{"dirty", T_OBJECT_EX, offsetof(ColorProfile, dirty), 0, "dirty"},
|
{"dirty", T_OBJECT_EX, offsetof(ColorProfile, dirty), 0, "dirty"},
|
||||||
|
{"ubo", T_OBJECT_EX, offsetof(ColorProfile, ubo), 0, "ubo"},
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -204,6 +221,7 @@ static PyMethodDef methods[] = {
|
|||||||
METHOD(reset_color, METH_O)
|
METHOD(reset_color, METH_O)
|
||||||
METHOD(set_color, METH_VARARGS)
|
METHOD(set_color, METH_VARARGS)
|
||||||
METHOD(set_configured_colors, METH_VARARGS)
|
METHOD(set_configured_colors, METH_VARARGS)
|
||||||
|
METHOD(copy_color_table, METH_VARARGS)
|
||||||
{NULL} /* Sentinel */
|
{NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
|
|
||||||
PyObject *dirty;
|
PyObject *dirty, *ubo;
|
||||||
uint32_t color_table[256];
|
uint32_t color_table[256];
|
||||||
uint32_t orig_color_table[256];
|
uint32_t orig_color_table[256];
|
||||||
DynamicColor configured, overridden;
|
DynamicColor configured, overridden;
|
||||||
|
|||||||
Reference in New Issue
Block a user