From d3f2620caf0f22ab2ccafc0547005df676810f64 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 10 Sep 2017 15:05:39 +0530 Subject: [PATCH] Migrate GL setup and error handling code --- kitty/gl.c | 27 ---------------- kitty/shaders.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 81 insertions(+), 32 deletions(-) diff --git a/kitty/gl.c b/kitty/gl.c index 809f6bbcb..6709ee960 100644 --- a/kitty/gl.c +++ b/kitty/gl.c @@ -49,12 +49,6 @@ static bool _enable_error_checking = 1; #define CHECK_ERROR if (_enable_error_checking) { SET_GL_ERR; if (PyErr_Occurred()) return NULL; } -static PyObject* -enable_automatic_error_checking(PyObject UNUSED *self, PyObject *val) { - _enable_error_checking = PyObject_IsTrue(val) ? true : false; - Py_RETURN_NONE; -} - static PyObject* Viewport(PyObject UNUSED *self, PyObject *args) { unsigned int x, y, w, h; @@ -165,25 +159,6 @@ CheckError(PyObject UNUSED *self) { CHECK_ERROR; Py_RETURN_NONE; } -static PyObject* -_glewInit(PyObject UNUSED *self) { -#ifndef __APPLE__ - GLenum err = glewInit(); - if (err != GLEW_OK) { - PyErr_Format(PyExc_RuntimeError, "GLEW init failed: %s", glewGetErrorString(err)); - return NULL; - } -#define ARB_TEST(name) \ - if (!GLEW_ARB_##name) { \ - PyErr_Format(PyExc_RuntimeError, "The OpenGL driver on this system is missing the required extension: ARB_%s", #name); \ - return NULL; \ - } - ARB_TEST(texture_storage); -#undef ARB_TEST -#endif - Py_RETURN_NONE; -} - static PyObject* GetString(PyObject UNUSED *self, PyObject *val) { const unsigned char *ans = glGetString(PyLong_AsUnsignedLong(val)); @@ -805,10 +780,8 @@ check_for_extensions(PyObject UNUSED *self) { } static PyMethodDef module_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}, {"get_uniform_block_size", (PyCFunction)get_uniform_block_size, METH_VARARGS, NULL}, {"get_uniform_block_offsets", (PyCFunction)get_uniform_block_offsets, METH_VARARGS, NULL}, diff --git a/kitty/shaders.c b/kitty/shaders.c index bea0becf8..fde0ff9ec 100644 --- a/kitty/shaders.c +++ b/kitty/shaders.c @@ -6,12 +6,86 @@ */ #include "data-types.h" +#ifdef __APPLE__ +#include +#include +#else +#include +#endif -#define GL_VERSION_MAJOR 3 -#define GL_VERSION_MINOR 3 -#define GLSL_VERSION (GL_VERSION_MAJOR * 100 + GL_VERSION_MINOR * 10) -enum Program { CELL_PROGRAM, CURSOR_PROGRAM, BORDERS_PROGRAM}; +// GL setup and error handling {{{ +// Required minimum OpenGL version +#define REQUIRED_VERSION_MAJOR 3 +#define REQUIRED_VERSION_MINOR 3 +#define GLSL_VERSION (REQUIRED_VERSION_MAJOR * 100 + REQUIRED_VERSION_MINOR * 10) + +static inline bool +set_error_from_gl() { + int code = glGetError(); + switch(code) { + case GL_NO_ERROR: return false; + 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_Format(PyExc_RuntimeError, "An unknown OpenGL error occurred with code: %d", code); break; + } + return true; +} + +static bool _enable_error_checking = false; +#define CHECK_ERROR if (_enable_error_checking) { if (set_error_from_gl()) return NULL; } + + +static PyObject* +glew_init(PyObject UNUSED *self) { +#ifndef __APPLE__ + GLenum err = glewInit(); + if (err != GLEW_OK) { + PyErr_Format(PyExc_RuntimeError, "GLEW init failed: %s", glewGetErrorString(err)); + return NULL; + } +#define ARB_TEST(name) \ + if (!GLEW_ARB_##name) { \ + PyErr_Format(PyExc_RuntimeError, "The OpenGL driver on this system is missing the required extension: ARB_%s", #name); \ + return NULL; \ + } + ARB_TEST(texture_storage); +#undef ARB_TEST +#endif + Py_RETURN_NONE; +} +// }}} + +enum Program { CELL_PROGRAM, CURSOR_PROGRAM, BORDERS_PROGRAM, NUM_PROGRAMS }; + +/* static GLuint program_ids[NUM_PROGRAMS] = {0}; */ + + +// Python API {{{ +static PyObject* +enable_automatic_error_checking(PyObject UNUSED *self, PyObject *val) { + _enable_error_checking = PyObject_IsTrue(val) ? true : false; + Py_RETURN_NONE; +} + +static PyMethodDef module_methods[] = { + {"enable_automatic_opengl_error_checking", (PyCFunction)enable_automatic_error_checking, METH_O, NULL}, + {"glewInit", (PyCFunction)glew_init, METH_NOARGS, NULL}, + {NULL, NULL, 0, NULL} /* Sentinel */ +}; bool init_shaders(PyObject *module) { @@ -19,6 +93,8 @@ init_shaders(PyObject *module) { C(CELL_PROGRAM); C(CURSOR_PROGRAM); C(BORDERS_PROGRAM); C(GLSL_VERSION); #undef C - PyModule_AddObject(module, "GL_VERSION_REQUIRED", Py_BuildValue("II", GL_VERSION_MAJOR, GL_VERSION_MINOR)); + PyModule_AddObject(module, "GL_VERSION_REQUIRED", Py_BuildValue("II", REQUIRED_VERSION_MAJOR, REQUIRED_VERSION_MINOR)); + if (PyModule_AddFunctions(module, module_methods) != 0) return false; return true; } +// }}}