diff --git a/kitty/gl.h b/kitty/gl.h index 811a2620e..d0a04a157 100644 --- a/kitty/gl.h +++ b/kitty/gl.h @@ -563,6 +563,24 @@ NamedBufferData(PyObject UNUSED *self, PyObject *args) { Py_RETURN_NONE; } +static PyObject* +replace_or_create_buffer(PyObject UNUSED *self, PyObject *args) { + int usage; + unsigned long size, prev_sz, target; + PyObject *address; + if (!PyArg_ParseTuple(args, "kkkO!i", &target, &size, &prev_sz, &PyLong_Type, &address, &usage)) return NULL; + void *data = PyLong_AsVoidPtr(address); + if (data == NULL) { PyErr_SetString(PyExc_TypeError, "Not a valid data pointer"); return NULL; } + glBindBuffer(GL_TEXTURE_BUFFER, target); + Py_BEGIN_ALLOW_THREADS; + if (prev_sz == 0 || prev_sz != size) glBufferData(GL_TEXTURE_BUFFER, size, data, usage); + else glBufferSubData(GL_TEXTURE_BUFFER, 0, size, data); + Py_END_ALLOW_THREADS; + CHECK_ERROR; + glBindBuffer(GL_TEXTURE_BUFFER, 0); + Py_RETURN_NONE; +} + static PyObject* TexParameteri(PyObject UNUSED *self, PyObject *args) { int target, name, param; @@ -717,6 +735,7 @@ int add_module_gl_constants(PyObject *module) { #define GL_METHODS \ {"enable_automatic_opengl_error_checking", (PyCFunction)enable_automatic_error_checking, METH_O, NULL}, \ {"copy_image_sub_data", (PyCFunction)copy_image_sub_data, METH_VARARGS, NULL}, \ + {"replace_or_create_buffer", (PyCFunction)replace_or_create_buffer, METH_VARARGS, NULL}, \ {"glewInit", (PyCFunction)_glewInit, METH_NOARGS, NULL}, \ {"check_for_extensions", (PyCFunction)check_for_extensions, METH_NOARGS, NULL}, \ METH(Viewport, METH_VARARGS) \ diff --git a/kitty/shaders.py b/kitty/shaders.py index 7fd34c99d..fbac94b8b 100644 --- a/kitty/shaders.py +++ b/kitty/shaders.py @@ -24,7 +24,8 @@ from .fast_data_types import ( GL_TEXTURE_BUFFER, GL_R32UI, GL_FLOAT, GL_ARRAY_BUFFER, glBindBuffer, glPixelStorei, glTexBuffer, glActiveTexture, glTexStorage3D, glCopyImageSubData, glTexSubImage3D, ITALIC, BOLD, SpriteMap, - glEnableVertexAttribArray, glVertexAttribPointer, copy_image_sub_data + glEnableVertexAttribArray, glVertexAttribPointer, copy_image_sub_data, + replace_or_create_buffer ) from .utils import safe_print @@ -42,6 +43,7 @@ class Sprites: # extensions one they become available. def __init__(self): + self.prev_sprite_map_sz = 0 self.xnum = self.ynum = 1 self.sampler_num = 0 self.buffer_sampler_num = 1 @@ -157,8 +159,9 @@ class Sprites: return glGenBuffers(1) def set_sprite_map(self, buf_id, data, usage=GL_STREAM_DRAW): + prev_sz, self.prev_sprite_map_sz = self.prev_sprite_map_sz, sizeof(data) + replace_or_create_buffer(buf_id, self.prev_sprite_map_sz, prev_sz, addressof(data), usage) self.bind_sprite_map(buf_id) - glNamedBufferData(buf_id, sizeof(data), addressof(data), usage) def bind_sprite_map(self, buf_id): glBindBuffer(GL_TEXTURE_BUFFER, buf_id)