diff --git a/count-lines-of-code b/count-lines-of-code index 67b76e6c7..eeddfa537 100755 --- a/count-lines-of-code +++ b/count-lines-of-code @@ -1,2 +1,2 @@ #!/bin/bash -cloc --exclude-list-file <(echo -e 'kitty/wcwidth9.h\nkitty/gl.c\nkitty/glfw.c\nkitty/glfw.h\nkitty/charsets.c\nkitty/key_encoding.py\nkitty/rgb.py') kitty +cloc --exclude-list-file <(echo -e 'kitty/wcwidth9.h\nkitty/glfw.c\nkitty/glfw.h\nkitty/charsets.c\nkitty/key_encoding.py\nkitty/rgb.py') kitty diff --git a/kitty/boss.py b/kitty/boss.py index 29500e2b1..0415577a3 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -13,10 +13,10 @@ mouse_cursor_pos, set_boss, viewport_size, wakeup ) from .fast_data_types import ( - GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GLFW_CURSOR, GLFW_CURSOR_HIDDEN, - GLFW_CURSOR_NORMAL, GLFW_MOUSE_BUTTON_1, GLFW_PRESS, GLFW_REPEAT, - ChildMonitor, Timers as _Timers, destroy_sprite_map, draw_borders, - glBlendFunc, glfw_post_empty_event, glViewport, layout_sprite_map + GLFW_CURSOR, GLFW_CURSOR_HIDDEN, GLFW_CURSOR_NORMAL, GLFW_MOUSE_BUTTON_1, + GLFW_PRESS, GLFW_REPEAT, ChildMonitor, Timers as _Timers, + destroy_sprite_map, draw_borders, glfw_post_empty_event, layout_sprite_map, + resize_gl_viewport ) from .fonts.render import render_cell_wrapper, set_font_family from .keys import ( @@ -95,7 +95,6 @@ def __init__(self, glfw_window, opts, args): self.cursor_blinking = True self.window_is_focused = True self.glfw_window_title = None - self.resize_gl_viewport = False self.shutting_down = False self.ui_timers = Timers() self.child_monitor = ChildMonitor( @@ -118,7 +117,6 @@ def __init__(self, glfw_window, opts, args): self.tab_manager = TabManager(opts, args) self.tab_manager.init(startup_session) layout_sprite_map(cell_size.width, cell_size.height, render_cell_wrapper) - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) self.glfw_window.set_click_cursor(False) self.show_mouse_cursor() self.start_cursor_blink() @@ -173,7 +171,7 @@ def on_window_resize(self, window, w, h): if w > 100 and h > 100: viewport_size.width, viewport_size.height = w, h self.tab_manager.resize() - self.resize_gl_viewport = True + resize_gl_viewport(w, h) glfw_post_empty_event() else: safe_print('Ignoring resize request for sizes under 100x100') @@ -364,9 +362,6 @@ def render(self): tab = self.active_tab if tab is None: return - if self.resize_gl_viewport: - glViewport(0, 0, viewport_size.width, viewport_size.height) - self.resize_gl_viewport = False if tab.title != self.glfw_window_title: self.glfw_window_title = tab.title self.glfw_window.set_title(self.glfw_window_title) diff --git a/kitty/data-types.c b/kitty/data-types.c index 3529386b4..1658ba115 100644 --- a/kitty/data-types.c +++ b/kitty/data-types.c @@ -84,7 +84,6 @@ static struct PyModuleDef module = { }; -extern bool add_module_gl_constants(PyObject*); extern int init_LineBuf(PyObject *); extern int init_HistoryBuf(PyObject *); extern int init_Cursor(PyObject *); @@ -123,7 +122,6 @@ PyInit_fast_data_types(void) { if (!init_ChildMonitor(m)) return NULL; if (!init_ColorProfile(m)) return NULL; if (!init_Screen(m)) return NULL; - if (!add_module_gl_constants(m)) return NULL; if (!init_glfw(m)) return NULL; if (!init_sprites(m)) return NULL; if (PySys_GetObject("debug_gl") == Py_True) { diff --git a/kitty/gl.c b/kitty/gl.c deleted file mode 100644 index 2ce4c20b7..000000000 --- a/kitty/gl.c +++ /dev/null @@ -1,861 +0,0 @@ -/* - * gl.c - * Copyright (C) 2016 Kovid Goyal - * - * Distributed under terms of the GPL3 license. - */ - -#include "data-types.h" -#ifdef __APPLE__ -#include -#include -#else -#include -#endif - -#define STRINGIFY(x) #x -#define METH(name, argtype) {STRINGIFY(gl##name), (PyCFunction)name, argtype, NULL}, - -static bool _enable_error_checking = 1; - -#ifndef GL_STACK_UNDERFLOW -#define GL_STACK_UNDERFLOW 0x0504 -#endif - -#ifndef GL_STACK_OVERFLOW -#define GL_STACK_OVERFLOW 0x0503 -#endif - -#define SET_GL_ERR \ - switch(glGetError()) { \ - case GL_NO_ERROR: break; \ - case GL_INVALID_ENUM: \ - PyErr_SetString(PyExc_ValueError, "An enum value is invalid (GL_INVALID_ENUM)"); break; \ - case GL_INVALID_VALUE: \ - PyErr_SetString(PyExc_ValueError, "An numeric value is invalid (GL_INVALID_VALUE)"); break; \ - case GL_INVALID_OPERATION: \ - PyErr_SetString(PyExc_ValueError, "This operation is not allowed in the current state (GL_INVALID_OPERATION)"); break; \ - case GL_INVALID_FRAMEBUFFER_OPERATION: \ - PyErr_SetString(PyExc_ValueError, "The framebuffer object is not complete (GL_INVALID_FRAMEBUFFER_OPERATION)"); break; \ - case GL_OUT_OF_MEMORY: \ - PyErr_SetString(PyExc_MemoryError, "There is not enough memory left to execute the command. (GL_OUT_OF_MEMORY)"); break; \ - case GL_STACK_UNDERFLOW: \ - PyErr_SetString(PyExc_OverflowError, "An attempt has been made to perform an operation that would cause an internal stack to underflow. (GL_STACK_UNDERFLOW)"); break; \ - case GL_STACK_OVERFLOW: \ - PyErr_SetString(PyExc_OverflowError, "An attempt has been made to perform an operation that would cause an internal stack to underflow. (GL_STACK_OVERFLOW)"); break; \ - default: \ - PyErr_SetString(PyExc_RuntimeError, "An unknown OpenGL error occurred."); break; \ - } - -#define CHECK_ERROR if (_enable_error_checking) { SET_GL_ERR; if (PyErr_Occurred()) return NULL; } - -static PyObject* -Viewport(PyObject UNUSED *self, PyObject *args) { - unsigned int x, y, w, h; - if (!PyArg_ParseTuple(args, "IIII", &x, &y, &w, &h)) return NULL; - glViewport(x, y, w, h); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -ClearColor(PyObject UNUSED *self, PyObject *args) { - float x, y, w, h; - if (!PyArg_ParseTuple(args, "ffff", &x, &y, &w, &h)) return NULL; - glClearColor(x, y, w, h); - CHECK_ERROR; - Py_RETURN_NONE; -} - -// Uniforms {{{ -static PyObject* -Uniform2ui(PyObject UNUSED *self, PyObject *args) { - int location; - unsigned int x, y; - if (!PyArg_ParseTuple(args, "iII", &location, &x, &y)) return NULL; - glUniform2ui(location, x, y); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -Uniform4ui(PyObject UNUSED *self, PyObject *args) { - int location; - unsigned int a, b, c, d; - if (!PyArg_ParseTuple(args, "iIIII", &location, &a, &b, &c, &d)) return NULL; - glUniform4ui(location, a, b, c, d); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -Uniform1uiv(PyObject UNUSED *self, PyObject *args) { - int location; - unsigned int count; - PyObject *value; - if (!PyArg_ParseTuple(args, "iIO", &location, &count, &value)) return NULL; - glUniform1uiv(location, count, (GLuint*)PyLong_AsVoidPtr(value)); - CHECK_ERROR; - Py_RETURN_NONE; -} - - -static PyObject* -Uniform2i(PyObject UNUSED *self, PyObject *args) { - int location; - int x, y; - if (!PyArg_ParseTuple(args, "iii", &location, &x, &y)) return NULL; - glUniform2i(location, x, y); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -Uniform1i(PyObject UNUSED *self, PyObject *args) { - int location; - int x; - if (!PyArg_ParseTuple(args, "ii", &location, &x)) return NULL; - glUniform1i(location, x); - CHECK_ERROR; - Py_RETURN_NONE; -} - - -static PyObject* -Uniform2f(PyObject UNUSED *self, PyObject *args) { - int location; - float x, y; - if (!PyArg_ParseTuple(args, "iff", &location, &x, &y)) return NULL; - glUniform2f(location, x, y); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -Uniform4f(PyObject UNUSED *self, PyObject *args) { - int location; - float x, y, a, b; - if (!PyArg_ParseTuple(args, "iffff", &location, &x, &y, &a, &b)) return NULL; - glUniform4f(location, x, y, a, b); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -Uniform3fv(PyObject UNUSED *self, PyObject *args) { - int location; - unsigned int count; - PyObject *l; - if (!PyArg_ParseTuple(args, "iIO!", &location, &count, &PyLong_Type, &l)) return NULL; - glUniform3fv(location, count, PyLong_AsVoidPtr(l)); - CHECK_ERROR; - Py_RETURN_NONE; -} -// }}} - - -static PyObject* -CheckError(PyObject UNUSED *self) { - CHECK_ERROR; Py_RETURN_NONE; -} - -static PyObject* -GetString(PyObject UNUSED *self, PyObject *val) { - const unsigned char *ans = glGetString(PyLong_AsUnsignedLong(val)); - if (ans == NULL) { SET_GL_ERR; return NULL; } - return PyBytes_FromString((const char*)ans); -} - -static PyObject* -Clear(PyObject UNUSED *self, PyObject *val) { - unsigned long m = PyLong_AsUnsignedLong(val); - glClear((GLbitfield)m); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -DrawArrays(PyObject UNUSED *self, PyObject *args) { - int mode, first; - unsigned int count; - if (!PyArg_ParseTuple(args, "iiI", &mode, &first, &count)) return NULL; - glDrawArrays(mode, first, count); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -MultiDrawArrays(PyObject UNUSED *self, PyObject *args) { - int mode; - unsigned int draw_count; - PyObject *a, *b; - if (!PyArg_ParseTuple(args, "iO!O!I", &mode, &PyLong_Type, &a, &PyLong_Type, &b, &draw_count)) return NULL; - glMultiDrawArrays(mode, PyLong_AsVoidPtr(a), PyLong_AsVoidPtr(b), draw_count); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -DrawArraysInstanced(PyObject UNUSED *self, PyObject *args) { - int mode, first; - unsigned int count, primcount; - if (!PyArg_ParseTuple(args, "iiII", &mode, &first, &count, &primcount)) return NULL; - glDrawArraysInstanced(mode, first, count, primcount); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -CreateProgram(PyObject UNUSED *self) { - GLuint ans = glCreateProgram(); - if (!ans) { SET_GL_ERR; return NULL; } - return PyLong_FromUnsignedLong(ans); -} - -static PyObject* -AttachShader(PyObject UNUSED *self, PyObject *args) { - unsigned int program_id, shader_id; - if (!PyArg_ParseTuple(args, "II", &program_id, &shader_id)) return NULL; - glAttachShader(program_id, shader_id); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -LinkProgram(PyObject UNUSED *self, PyObject *val) { - unsigned long program_id = PyLong_AsUnsignedLong(val); - glLinkProgram(program_id); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -GetProgramiv(PyObject UNUSED *self, PyObject *args) { - unsigned int program_id; - int pname, ans = 0; - if (!PyArg_ParseTuple(args, "Ii", &program_id, &pname)) return NULL; - glGetProgramiv(program_id, pname, &ans); - CHECK_ERROR; - return PyLong_FromLong((long)ans); -} - -static PyObject* -GetProgramInfoLog(PyObject UNUSED *self, PyObject *val) { - unsigned long program_id = PyLong_AsUnsignedLong(val); - int log_len = 0; - GLchar *buf = NULL; - glGetProgramiv(program_id, GL_INFO_LOG_LENGTH, &log_len); - buf = PyMem_Calloc(log_len + 10, sizeof(GLchar)); - if (buf == NULL) return PyErr_NoMemory(); - glGetProgramInfoLog(program_id, log_len, &log_len, buf); - PyObject *ans = PyBytes_FromStringAndSize(buf, log_len); - PyMem_Free(buf); - return ans; -} - -static PyObject* -GetShaderInfoLog(PyObject UNUSED *self, PyObject *val) { - unsigned long program_id = PyLong_AsUnsignedLong(val); - int log_len = 0; - GLchar *buf = NULL; - glGetShaderiv(program_id, GL_INFO_LOG_LENGTH, &log_len); - buf = PyMem_Calloc(log_len + 10, sizeof(GLchar)); - if (buf == NULL) return PyErr_NoMemory(); - glGetShaderInfoLog(program_id, log_len, &log_len, buf); - PyObject *ans = PyBytes_FromStringAndSize(buf, log_len); - PyMem_Free(buf); - return ans; -} - -static PyObject* -ActiveTexture(PyObject UNUSED *self, PyObject *val) { - long tex_id = PyLong_AsLong(val); - glActiveTexture(tex_id); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -DeleteProgram(PyObject UNUSED *self, PyObject *val) { - unsigned long program_id = PyLong_AsUnsignedLong(val); - glDeleteProgram(program_id); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -DeleteShader(PyObject UNUSED *self, PyObject *val) { - unsigned long program_id = PyLong_AsUnsignedLong(val); - glDeleteShader(program_id); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -GenVertexArrays(PyObject UNUSED *self, PyObject *val) { - GLuint arrays[256] = {0}; - unsigned long n = PyLong_AsUnsignedLong(val); - if (n > 256) { PyErr_SetString(PyExc_ValueError, "Generating more than 256 arrays in a single call is not supported"); return NULL; } - glGenVertexArrays(n, arrays); - CHECK_ERROR; - if (n == 1) return PyLong_FromUnsignedLong((unsigned long)arrays[0]); - PyObject *ans = PyTuple_New(n); - if (ans == NULL) return PyErr_NoMemory(); - for (size_t i = 0; i < n; i++) { - PyObject *t = PyLong_FromUnsignedLong((unsigned long)arrays[i]); - if (t == NULL) { Py_DECREF(ans); return PyErr_NoMemory(); } - PyTuple_SET_ITEM(ans, i, t); - } - return ans; -} - -static PyObject* -GenTextures(PyObject UNUSED *self, PyObject *val) { - GLuint arrays[256] = {0}; - unsigned long n = PyLong_AsUnsignedLong(val); - if (n > 256) { PyErr_SetString(PyExc_ValueError, "Generating more than 256 textures in a single call is not supported"); return NULL; } - glGenTextures(n, arrays); - CHECK_ERROR; - if (n == 1) return PyLong_FromUnsignedLong((unsigned long)arrays[0]); - PyObject *ans = PyTuple_New(n); - if (ans == NULL) return PyErr_NoMemory(); - for (size_t i = 0; i < n; i++) { - PyObject *t = PyLong_FromUnsignedLong((unsigned long)arrays[i]); - if (t == NULL) { Py_DECREF(ans); return PyErr_NoMemory(); } - PyTuple_SET_ITEM(ans, i, t); - } - return ans; -} - -static PyObject* -GenBuffers(PyObject UNUSED *self, PyObject *val) { - GLuint arrays[256] = {0}; - unsigned long n = PyLong_AsUnsignedLong(val); - if (n > 256) { PyErr_SetString(PyExc_ValueError, "Generating more than 256 buffers in a single call is not supported"); return NULL; } - glGenBuffers(n, arrays); - CHECK_ERROR; - if (n == 1) return PyLong_FromUnsignedLong((unsigned long)arrays[0]); - PyObject *ans = PyTuple_New(n); - if (ans == NULL) return PyErr_NoMemory(); - for (size_t i = 0; i < n; i++) { - PyObject *t = PyLong_FromUnsignedLong((unsigned long)arrays[i]); - if (t == NULL) { Py_DECREF(ans); return PyErr_NoMemory(); } - PyTuple_SET_ITEM(ans, i, t); - } - return ans; -} - - -static PyObject* -CreateShader(PyObject UNUSED *self, PyObject *val) { - long shader_type = PyLong_AsLong(val); - GLuint ans = glCreateShader(shader_type); - CHECK_ERROR; - return PyLong_FromUnsignedLong(ans); -} - -static PyObject* -ShaderSource(PyObject UNUSED *self, PyObject *args) { - char *src; Py_ssize_t src_len = 0; - unsigned int shader_id; - if(!PyArg_ParseTuple(args, "Is#", &shader_id, &src, &src_len)) return NULL; - glShaderSource(shader_id, 1, (const GLchar **)&src, NULL); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -CompileShader(PyObject UNUSED *self, PyObject *val) { - unsigned long shader_id = PyLong_AsUnsignedLong(val); - glCompileShader((GLuint)shader_id); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -GetShaderiv(PyObject UNUSED *self, PyObject *args) { - unsigned int program_id; - int pname, ans = 0; - if (!PyArg_ParseTuple(args, "Ii", &program_id, &pname)) return NULL; - glGetShaderiv(program_id, pname, &ans); - CHECK_ERROR; - return PyLong_FromLong((long)ans); -} - -static PyObject* -GetUniformLocation(PyObject UNUSED *self, PyObject *args) { - char *name; - unsigned int program_id; - if(!PyArg_ParseTuple(args, "Is", &program_id, &name)) return NULL; - GLint ans = glGetUniformLocation(program_id, name); - CHECK_ERROR; - return PyLong_FromLong((long) ans); -} - -static PyObject* -GetUniformBlockIndex(PyObject UNUSED *self, PyObject *args) { - char *name; - unsigned int program_id; - if(!PyArg_ParseTuple(args, "Is", &program_id, &name)) return NULL; - GLuint ans = glGetUniformBlockIndex(program_id, name); - if (ans == GL_INVALID_INDEX) { PyErr_SetString(PyExc_ValueError, "No such uniform block is active"); return NULL; } - return PyLong_FromUnsignedLong((unsigned long) ans); -} - -static PyObject* -GetAttribLocation(PyObject UNUSED *self, PyObject *args) { - char *name; - unsigned int program_id; - if(!PyArg_ParseTuple(args, "Is", &program_id, &name)) return NULL; - GLint ans = glGetAttribLocation(program_id, name); - CHECK_ERROR; - return PyLong_FromLong((long) ans); -} - -static PyObject* -get_uniform_block_size(PyObject UNUSED *self, PyObject *args) { - unsigned int program_id, block_index; - if(!PyArg_ParseTuple(args, "II", &program_id, &block_index)) return NULL; - GLint ans; - glGetActiveUniformBlockiv(program_id, block_index, GL_UNIFORM_BLOCK_DATA_SIZE, &ans); - CHECK_ERROR; - return PyLong_FromLong((long) ans); -} - -static PyObject* -get_uniform_block_offsets(PyObject UNUSED *self, PyObject *args) { - unsigned int program_id; - PyObject *pynames; - if(!PyArg_ParseTuple(args, "IO", &program_id, &pynames)) return NULL; - if (!PySequence_Check(pynames)) { PyErr_SetString(PyExc_TypeError, "names must be a sequence"); return NULL; } - GLsizei count = PySequence_Size(pynames); - char **names = PyMem_Calloc(count, sizeof(char*)); - GLuint *indices = PyMem_Calloc(count, sizeof(GLuint)); - GLint *offsets = PyMem_Calloc(count, sizeof(GLint)); - PyObject *ans = PyTuple_New(count); - if (ans == NULL || indices == NULL || names == NULL) return PyErr_NoMemory(); - for (GLsizei i = 0; i < count; i++) { - PyObject *t = PySequence_ITEM(pynames, i); - names[i] = PyUnicode_AsUTF8(t); - Py_CLEAR(t); - } - glGetUniformIndices(program_id, count, (void*)names, indices); - glGetActiveUniformsiv(program_id, count, indices, GL_UNIFORM_OFFSET, offsets); - for (GLsizei i = 0; i < count; i++) PyTuple_SET_ITEM(ans, i, PyLong_FromLong(offsets[i])); - PyMem_Free(names); PyMem_Free(indices); PyMem_Free(offsets); - if (_enable_error_checking) { - SET_GL_ERR; - if (PyErr_Occurred()) { Py_CLEAR(ans); return NULL; } - } - return ans; -} - -static PyObject* -UseProgram(PyObject UNUSED *self, PyObject *val) { - unsigned long program_id = PyLong_AsUnsignedLong(val); - glUseProgram(program_id); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -BindVertexArray(PyObject UNUSED *self, PyObject *val) { - unsigned long program_id = PyLong_AsUnsignedLong(val); - glBindVertexArray(program_id); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -GetIntegerv(PyObject UNUSED *self, PyObject *val) { - unsigned long program_id = PyLong_AsUnsignedLong(val); - GLint ans = 0; - glGetIntegerv(program_id, &ans); - CHECK_ERROR; - return PyLong_FromLong((long)ans); -} - -static PyObject* -BindTexture(PyObject UNUSED *self, PyObject *args) { - unsigned int tex_id; int target; - if (!PyArg_ParseTuple(args, "iI", &target, &tex_id)) return NULL; - glBindTexture(target, tex_id); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -TexStorage3D(PyObject UNUSED *self, PyObject *args) { - int target, fmt; - unsigned int levels, width, height, depth; - if (!PyArg_ParseTuple(args, "iIiIII", &target, &levels, &fmt, &width, &height, &depth)) return NULL; - glTexStorage3D(target, levels, fmt, width, height, depth); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -#if defined(__APPLE__) && !defined(glCopyImageSubData) -CopyImageSubData(PyObject UNUSED *self, UNUSED PyObject *args) { - PyErr_SetString(PyExc_RuntimeError, "OpenGL is missing the required ARB_copy_image extension"); - return NULL; -} -#else -CopyImageSubData(PyObject UNUSED *self, PyObject *args) { - if(!GLEW_ARB_copy_image) { - PyErr_SetString(PyExc_RuntimeError, "OpenGL is missing the required ARB_copy_image extension"); - return NULL; - } - int src_target, src_level, srcX, srcY, srcZ, dest_target, dest_level, destX, destY, destZ; - unsigned int src, dest, width, height, depth; - if (!PyArg_ParseTuple(args, "IiiiiiIiiiiiIII", - &src, &src_target, &src_level, &srcX, &srcY, &srcZ, - &dest, &dest_target, &dest_level, &destX, &destY, &destZ, - &width, &height, &depth - )) return NULL; - glCopyImageSubData(src, src_target, src_level, srcX, srcY, srcZ, dest, dest_target, dest_level, destX, destY, destZ, width, height, depth); - CHECK_ERROR; - Py_RETURN_NONE; -} -#endif - -static PyObject* -copy_image_sub_data(PyObject UNUSED *self, PyObject *args) { - int src_target, dest_target; - unsigned int width, height, num_levels; - if (!PyArg_ParseTuple(args, "iiIII", &src_target, &dest_target, &width, &height, &num_levels)) return NULL; - uint8_t *src = (uint8_t*)PyMem_Malloc(5 * width * height * num_levels); - if (src == NULL) return PyErr_NoMemory(); - uint8_t *dest = src + (4 * width * height * num_levels); - glBindTexture(GL_TEXTURE_2D_ARRAY, src_target); - glGetTexImage(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, GL_UNSIGNED_BYTE, src); - glBindTexture(GL_TEXTURE_2D_ARRAY, dest_target); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - for(unsigned int i = 0; i < width * height * num_levels; i++) dest[i] = src[4*i]; - glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, width, height, num_levels, GL_RED, GL_UNSIGNED_BYTE, dest); - PyMem_Free(src); - Py_RETURN_NONE; -} - -static PyObject* -TexSubImage3D(PyObject UNUSED *self, PyObject *args) { - int target, level, x, y, z, fmt, type; - unsigned int width, height, depth; - PyObject *pixels; - if (!PyArg_ParseTuple(args, "iiiiiIIIiiO!", &target, &level, &x, &y, &z, &width, &height, &depth, &fmt, &type, &PyLong_Type, &pixels)) return NULL; - void *data = PyLong_AsVoidPtr(pixels); - if (data == NULL) { PyErr_SetString(PyExc_TypeError, "Not a valid data pointer"); return NULL; } - glTexSubImage3D(target, level, x, y, z, width, height, depth, fmt, type, data); - CHECK_ERROR; - Py_RETURN_NONE; -} - - -static PyObject* -GetTexImage(PyObject UNUSED *self, PyObject *args) { - int target, level, fmt, type; - PyObject *pixels; - if (!PyArg_ParseTuple(args, "iiiiO!", &target, &level, &fmt, &type, &PyLong_Type, &pixels)) return NULL; - void *data = PyLong_AsVoidPtr(pixels); - if (data == NULL) { PyErr_SetString(PyExc_TypeError, "Not a valid data pointer"); return NULL; } - glGetTexImage(target, level, fmt, type, data); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -GetBufferSubData(PyObject UNUSED *self, PyObject *args) { - int buftype; - unsigned long size, target, offset; - PyObject *address; - if (!PyArg_ParseTuple(args, "ikkkO!", &buftype, &target, &size, &offset, &PyLong_Type, &address)) return NULL; - void *data = PyLong_AsVoidPtr(address); - if (data == NULL) { PyErr_SetString(PyExc_TypeError, "Not a valid data pointer"); return NULL; } - glBindBuffer(buftype, target); - glGetBufferSubData(buftype, offset, size, data); - CHECK_ERROR; - glBindBuffer(buftype, 0); - Py_RETURN_NONE; -} - -static PyObject* -replace_or_create_buffer(PyObject UNUSED *self, PyObject *args) { - int usage, buftype; - unsigned long size, prev_sz, target; - void *data = NULL; - PyObject *address; - if (!PyArg_ParseTuple(args, "kkkO!ii", &target, &size, &prev_sz, &PyLong_Type, &address, &usage, &buftype)) return NULL; - data = PyLong_AsVoidPtr(address); - glBindBuffer(buftype, target); - if (prev_sz == 0 || prev_sz != size) glBufferData(buftype, size, data, usage); - else glBufferSubData(buftype, 0, size, data); - CHECK_ERROR; - glBindBuffer(buftype, 0); - Py_RETURN_NONE; -} - -static PyObject* -MapBuffer(PyObject UNUSED *self, PyObject *args) { - int target, access; - if (!PyArg_ParseTuple(args, "ii", &target, &access)) return NULL; - void *address = glMapBuffer(target, access); - if (address == NULL) { SET_GL_ERR; return NULL; } - return PyLong_FromVoidPtr(address); -} - -static PyObject* -UnmapBuffer(PyObject UNUSED *self, PyObject *args) { - int target; - if (!PyArg_ParseTuple(args, "i", &target)) return NULL; - if (!glUnmapBuffer(target)) { SET_GL_ERR; return NULL; } - Py_RETURN_NONE; -} - -static PyObject* -TexParameteri(PyObject UNUSED *self, PyObject *args) { - int target, name, param; - if (!PyArg_ParseTuple(args, "iii", &target, &name, ¶m)) return NULL; - glTexParameteri(target, name, param); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -PixelStorei(PyObject UNUSED *self, PyObject *args) { - int name, param; - if (!PyArg_ParseTuple(args, "ii", &name, ¶m)) return NULL; - glPixelStorei(name, param); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -BindBuffer(PyObject UNUSED *self, PyObject *args) { - int tgt; unsigned int buf_id; - if (!PyArg_ParseTuple(args, "iI", &tgt, &buf_id)) return NULL; - glBindBuffer(tgt, buf_id); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -BindBufferBase(PyObject UNUSED *self, PyObject *args) { - int tgt; unsigned int index, buf_id; - if (!PyArg_ParseTuple(args, "iII", &tgt, &index, &buf_id)) return NULL; - glBindBufferBase(tgt, index, buf_id); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -TexBuffer(PyObject UNUSED *self, PyObject *args) { - int tgt, fmt; unsigned int buf_id; - if (!PyArg_ParseTuple(args, "iiI", &tgt, &fmt, &buf_id)) return NULL; - glTexBuffer(tgt, fmt, buf_id); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -DeleteTexture(PyObject UNUSED *self, PyObject *val) { - GLuint tex_id = (GLuint)PyLong_AsUnsignedLong(val); - glDeleteTextures(1, &tex_id); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -DeleteBuffer(PyObject UNUSED *self, PyObject *val) { - GLuint tex_id = (GLuint)PyLong_AsUnsignedLong(val); - glDeleteBuffers(1, &tex_id); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -DeleteVertexArray(PyObject UNUSED *self, PyObject *val) { - GLuint tex_id = (GLuint)PyLong_AsUnsignedLong(val); - glDeleteVertexArrays(1, &tex_id); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -BlendFunc(PyObject UNUSED *self, PyObject *args) { - int s, d; - if (!PyArg_ParseTuple(args, "ii", &s, &d)) return NULL; - glBlendFunc(s, d); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -Enable(PyObject UNUSED *self, PyObject *val) { - long x = PyLong_AsLong(val); - glEnable(x); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -Disable(PyObject UNUSED *self, PyObject *val) { - long x = PyLong_AsLong(val); - glDisable(x); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -EnableVertexAttribArray(PyObject UNUSED *self, PyObject *val) { - long x = PyLong_AsLong(val); - glEnableVertexAttribArray(x); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -VertexAttribPointer(PyObject UNUSED *self, PyObject *args) { - unsigned int index; - int type, normalized, size, stride; - unsigned long offset; - if (!PyArg_ParseTuple(args, "Iiipik", &index, &size, &type, &normalized, &stride, &offset)) return NULL; - switch(type) { - case GL_BYTE: - case GL_UNSIGNED_BYTE: - case GL_SHORT: - case GL_UNSIGNED_SHORT: - case GL_INT: - case GL_UNSIGNED_INT: - glVertexAttribIPointer(index, size, type, stride, (GLvoid*)offset); - break; - default: - glVertexAttribPointer(index, size, type, normalized ? GL_TRUE : GL_FALSE, stride, (GLvoid*)offset); - break; - } - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -VertexAttribDivisor(PyObject UNUSED *self, PyObject *args) { - unsigned int index, divisor; - if (!PyArg_ParseTuple(args, "II", &index, &divisor)) return NULL; - glVertexAttribDivisor(index, divisor); - CHECK_ERROR; - Py_RETURN_NONE; -} - -static PyObject* -Flush(PyObject UNUSED *self) { - glFinish(); - Py_RETURN_NONE; -} - -static PyObject* -Finish(PyObject UNUSED *self) { - glFinish(); - Py_RETURN_NONE; -} - -static PyObject* -check_for_extensions(PyObject UNUSED *self) { - GLint n = 0, i, left = 2; - glGetIntegerv(GL_NUM_EXTENSIONS, &n); - bool texture_storage = false; -#define CHECK(name) if (!name) { \ - if (strstr((const char*)ext, "GL_ARB_" #name) == (const char *)ext) { left--; name = true; } \ -} - for (i = 0; i < n; i++) { - const GLubyte *ext = glGetStringi(GL_EXTENSIONS, i); - CHECK(texture_storage); - if (left < 1) break; - } -#undef CHECK - if (left > 0) { -#define CHECK(name) if (!name) { PyErr_Format(PyExc_RuntimeError, "The OpenGL driver on this system is missing the required extension: GL_ARB_%s", #name); return NULL; } - CHECK(texture_storage); -#undef CHECK - } - Py_RETURN_NONE; -} - -static PyMethodDef module_methods[] = { - {"copy_image_sub_data", (PyCFunction)copy_image_sub_data, METH_VARARGS, NULL}, - {"replace_or_create_buffer", (PyCFunction)replace_or_create_buffer, METH_VARARGS, NULL}, - {"check_for_extensions", (PyCFunction)check_for_extensions, METH_NOARGS, NULL}, - {"get_uniform_block_size", (PyCFunction)get_uniform_block_size, METH_VARARGS, NULL}, - {"get_uniform_block_offsets", (PyCFunction)get_uniform_block_offsets, METH_VARARGS, NULL}, - METH(Viewport, METH_VARARGS) - METH(CheckError, METH_NOARGS) - METH(ClearColor, METH_VARARGS) - METH(GetProgramiv, METH_VARARGS) - METH(GetShaderiv, METH_VARARGS) - METH(Uniform2ui, METH_VARARGS) - METH(Uniform4ui, METH_VARARGS) - METH(Uniform1uiv, METH_VARARGS) - METH(Uniform2i, METH_VARARGS) - METH(Uniform1i, METH_VARARGS) - METH(Uniform2f, METH_VARARGS) - METH(Uniform4f, METH_VARARGS) - METH(Uniform3fv, METH_VARARGS) - METH(GetUniformLocation, METH_VARARGS) - METH(GetUniformBlockIndex, METH_VARARGS) - METH(GetAttribLocation, METH_VARARGS) - METH(ShaderSource, METH_VARARGS) - METH(CompileShader, METH_O) - METH(DeleteTexture, METH_O) - METH(DeleteBuffer, METH_O) - METH(DeleteVertexArray, METH_O) - METH(GetString, METH_O) - METH(GetIntegerv, METH_O) - METH(Clear, METH_O) - METH(CreateShader, METH_O) - METH(GenVertexArrays, METH_O) - METH(GenTextures, METH_O) - METH(GenBuffers, METH_O) - METH(LinkProgram, METH_O) - METH(UseProgram, METH_O) - METH(BindVertexArray, METH_O) - METH(DeleteProgram, METH_O) - METH(DeleteShader, METH_O) - METH(Enable, METH_O) - METH(Disable, METH_O) - METH(EnableVertexAttribArray, METH_O) - METH(VertexAttribPointer, METH_VARARGS) - METH(VertexAttribDivisor, METH_VARARGS) - METH(GetProgramInfoLog, METH_O) - METH(GetShaderInfoLog, METH_O) - METH(ActiveTexture, METH_O) - METH(DrawArraysInstanced, METH_VARARGS) - METH(DrawArrays, METH_VARARGS) - METH(MultiDrawArrays, METH_VARARGS) - METH(CreateProgram, METH_NOARGS) - METH(AttachShader, METH_VARARGS) - METH(BindTexture, METH_VARARGS) - METH(TexParameteri, METH_VARARGS) - METH(MapBuffer, METH_VARARGS) - METH(UnmapBuffer, METH_VARARGS) - METH(PixelStorei, METH_VARARGS) - METH(BindBuffer, METH_VARARGS) - METH(BindBufferBase, METH_VARARGS) - METH(TexBuffer, METH_VARARGS) - METH(TexStorage3D, METH_VARARGS) - METH(CopyImageSubData, METH_VARARGS) - METH(TexSubImage3D, METH_VARARGS) - METH(GetTexImage, METH_VARARGS) - METH(GetBufferSubData, METH_VARARGS) - METH(BlendFunc, METH_VARARGS) - METH(Finish, METH_NOARGS) - METH(Flush, METH_NOARGS) - - {NULL, NULL, 0, NULL} /* Sentinel */ -}; - -bool -add_module_gl_constants(PyObject *module) { - if (PyModule_AddFunctions(module, module_methods) != 0) return false; - return true; -} - - - diff --git a/kitty/main.py b/kitty/main.py index 944851a23..96e6e3a0c 100644 --- a/kitty/main.py +++ b/kitty/main.py @@ -17,16 +17,16 @@ appname, config_dir, isosx, logo_data_file, str_version, viewport_size ) from .fast_data_types import ( - GL_COLOR_BUFFER_BIT, GL_VERSION_REQUIRED, GLFW_CONTEXT_VERSION_MAJOR, + GL_VERSION_REQUIRED, GLFW_CONTEXT_VERSION_MAJOR, GLFW_CONTEXT_VERSION_MINOR, GLFW_DECORATED, GLFW_OPENGL_CORE_PROFILE, GLFW_OPENGL_FORWARD_COMPAT, GLFW_OPENGL_PROFILE, GLFW_SAMPLES, - GLFW_STENCIL_BITS, Window, change_wcwidth, check_for_extensions, glClear, - glClearColor, glewInit, glfw_init, glfw_init_hint_string, + GLFW_STENCIL_BITS, Window, change_wcwidth, check_for_extensions, + clear_buffers, glewInit, glfw_init, glfw_init_hint_string, glfw_set_error_callback, glfw_swap_interval, glfw_terminate, glfw_window_hint ) from .layout import all_layouts -from .utils import detach, safe_print +from .utils import color_as_int, detach, safe_print try: from .fast_data_types import GLFW_X11_WM_CLASS_NAME, GLFW_X11_WM_CLASS_CLASS @@ -153,18 +153,6 @@ def setup_opengl(opts): glfw_window_hint(GLFW_STENCIL_BITS, 8) -def clear_buffers(window, opts): - bg = opts.background - glClearColor(bg.red / 255, bg.green / 255, bg.blue / 255, 1) - glfw_swap_interval(0) - glClear(GL_COLOR_BUFFER_BIT) - window.swap_buffers() - glClear(GL_COLOR_BUFFER_BIT) - # We dont turn this on as it causes rendering performance to be much worse, - # for example, dragging the mouse to select is laggy - # glfw_swap_interval(1) - - def run_app(opts, args): setup_opengl(opts) load_cached_values() @@ -204,7 +192,11 @@ def run_app(opts, args): glewInit() boss = Boss(window, opts, args) boss.start() - clear_buffers(window, opts) + glfw_swap_interval(0) + clear_buffers(window.swap_buffers, color_as_int(opts.background)) + # We dont turn this on as it causes rendering performance to be much worse, + # for example, dragging the mouse to select is laggy + # glfw_swap_interval(1) try: boss.child_monitor.main_loop() finally: diff --git a/kitty/shaders.c b/kitty/shaders.c index cca673722..6c559c205 100644 --- a/kitty/shaders.c +++ b/kitty/shaders.c @@ -83,6 +83,7 @@ glew_init(PyObject UNUSED *self) { ARB_TEST(texture_storage); #undef ARB_TEST #endif + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); Py_RETURN_NONE; } // }}} @@ -857,11 +858,54 @@ PYWRAP1(layout_sprite_map) { Py_RETURN_NONE; } +PYWRAP1(resize_gl_viewport) { + unsigned int w, h; PA("II", &w, &h); + glViewport(0, 0, w, h); + Py_RETURN_NONE; +} + +PYWRAP1(clear_buffers) { + PyObject *swap_buffers; + unsigned int bg; + PA("OI", &swap_buffers, &bg); +#define C(shift) ((float)((bg >> shift) & 0xff)) / 255.0 + glClearColor(C(16), C(8), C(0), 1); +#undef C + glClear(GL_COLOR_BUFFER_BIT); + PyObject *ret = PyObject_CallFunctionObjArgs(swap_buffers, NULL); + if (ret == NULL) return NULL; + Py_DECREF(ret); + glClear(GL_COLOR_BUFFER_BIT); + Py_RETURN_NONE; +} + +PYWRAP0(check_for_extensions) { + GLint n = 0, i, left = 2; + glGetIntegerv(GL_NUM_EXTENSIONS, &n); + bool texture_storage = false; +#define CHECK(name) if (!name) { \ + if (strstr((const char*)ext, "GL_ARB_" #name) == (const char *)ext) { left--; name = true; } \ +} + for (i = 0; i < n; i++) { + const GLubyte *ext = glGetStringi(GL_EXTENSIONS, i); + CHECK(texture_storage); + if (left < 1) break; + } +#undef CHECK + if (left > 0) { +#define CHECK(name) if (!name) { PyErr_Format(PyExc_RuntimeError, "The OpenGL driver on this system is missing the required extension: GL_ARB_%s", #name); return NULL; } + CHECK(texture_storage); +#undef CHECK + } + Py_RETURN_NONE; +} + #define M(name, arg_type) {#name, (PyCFunction)name, arg_type, NULL} #define MW(name, arg_type) {#name, (PyCFunction)py##name, arg_type, NULL} static PyMethodDef module_methods[] = { {"glewInit", (PyCFunction)glew_init, METH_NOARGS, NULL}, M(compile_program, METH_VARARGS), + MW(check_for_extensions, METH_NOARGS), MW(create_vao, METH_NOARGS), MW(remove_vao, METH_O), MW(bind_vertex_array, METH_O), @@ -881,6 +925,8 @@ static PyMethodDef module_methods[] = { MW(draw_cells, METH_VARARGS), MW(layout_sprite_map, METH_VARARGS), MW(destroy_sprite_map, METH_NOARGS), + MW(resize_gl_viewport, METH_VARARGS), + MW(clear_buffers, METH_VARARGS), {NULL, NULL, 0, NULL} /* Sentinel */ };