mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-28 19:21:38 +02:00
Migrate GL setup and error handling code
This commit is contained in:
27
kitty/gl.c
27
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; }
|
#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*
|
static PyObject*
|
||||||
Viewport(PyObject UNUSED *self, PyObject *args) {
|
Viewport(PyObject UNUSED *self, PyObject *args) {
|
||||||
unsigned int x, y, w, h;
|
unsigned int x, y, w, h;
|
||||||
@@ -165,25 +159,6 @@ CheckError(PyObject UNUSED *self) {
|
|||||||
CHECK_ERROR; Py_RETURN_NONE;
|
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*
|
static PyObject*
|
||||||
GetString(PyObject UNUSED *self, PyObject *val) {
|
GetString(PyObject UNUSED *self, PyObject *val) {
|
||||||
const unsigned char *ans = glGetString(PyLong_AsUnsignedLong(val));
|
const unsigned char *ans = glGetString(PyLong_AsUnsignedLong(val));
|
||||||
@@ -805,10 +780,8 @@ check_for_extensions(PyObject UNUSED *self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static PyMethodDef module_methods[] = {
|
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},
|
{"copy_image_sub_data", (PyCFunction)copy_image_sub_data, METH_VARARGS, NULL},
|
||||||
{"replace_or_create_buffer", (PyCFunction)replace_or_create_buffer, 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},
|
{"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_size", (PyCFunction)get_uniform_block_size, METH_VARARGS, NULL},
|
||||||
{"get_uniform_block_offsets", (PyCFunction)get_uniform_block_offsets, METH_VARARGS, NULL},
|
{"get_uniform_block_offsets", (PyCFunction)get_uniform_block_offsets, METH_VARARGS, NULL},
|
||||||
|
|||||||
@@ -6,12 +6,86 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "data-types.h"
|
#include "data-types.h"
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <OpenGL/gl3.h>
|
||||||
|
#include <OpenGL/gl3ext.h>
|
||||||
|
#else
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#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
|
bool
|
||||||
init_shaders(PyObject *module) {
|
init_shaders(PyObject *module) {
|
||||||
@@ -19,6 +93,8 @@ init_shaders(PyObject *module) {
|
|||||||
C(CELL_PROGRAM); C(CURSOR_PROGRAM); C(BORDERS_PROGRAM);
|
C(CELL_PROGRAM); C(CURSOR_PROGRAM); C(BORDERS_PROGRAM);
|
||||||
C(GLSL_VERSION);
|
C(GLSL_VERSION);
|
||||||
#undef C
|
#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;
|
return true;
|
||||||
}
|
}
|
||||||
|
// }}}
|
||||||
|
|||||||
Reference in New Issue
Block a user