From 288bb034b5e7264f97246dee14400e049c111b32 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 13 Jun 2023 14:54:20 +0530 Subject: [PATCH] Remove duplicate definitions of linear2srgb functions in shaders --- kitty/bgimage_fragment.glsl | 1 - kitty/bgimage_vertex.glsl | 1 - kitty/blit_fragment.glsl | 10 +--------- kitty/blit_vertex.glsl | 1 - kitty/border_fragment.glsl | 1 - kitty/border_vertex.glsl | 11 ++--------- kitty/cell_fragment.glsl | 19 ++----------------- kitty/cell_vertex.glsl | 1 - kitty/gl.c | 4 ++-- kitty/gl.h | 2 +- kitty/graphics_fragment.glsl | 1 - kitty/graphics_vertex.glsl | 1 - kitty/linear2srgb.glsl | 15 +++++++++++++++ kitty/shaders.c | 7 ++++--- kitty/tint_fragment.glsl | 2 -- kitty/tint_vertex.glsl | 1 - kitty/utils.py | 24 ++++++++++++++---------- 17 files changed, 41 insertions(+), 61 deletions(-) create mode 100644 kitty/linear2srgb.glsl diff --git a/kitty/bgimage_fragment.glsl b/kitty/bgimage_fragment.glsl index bd15691a6..231b628e4 100644 --- a/kitty/bgimage_fragment.glsl +++ b/kitty/bgimage_fragment.glsl @@ -1,4 +1,3 @@ -#version GLSL_VERSION uniform sampler2D image; uniform float opacity; diff --git a/kitty/bgimage_vertex.glsl b/kitty/bgimage_vertex.glsl index 4bb6c921d..fb5ccd05e 100644 --- a/kitty/bgimage_vertex.glsl +++ b/kitty/bgimage_vertex.glsl @@ -1,4 +1,3 @@ -#version GLSL_VERSION #define left 0 #define top 1 #define right 2 diff --git a/kitty/blit_fragment.glsl b/kitty/blit_fragment.glsl index 74e243336..0eea558a5 100644 --- a/kitty/blit_fragment.glsl +++ b/kitty/blit_fragment.glsl @@ -1,18 +1,10 @@ -#version GLSL_VERSION +#pragma kitty_include_shader uniform sampler2D image; in vec2 texcoord; out vec4 color; -float linear2srgb(float x) { - // Linear to sRGB conversion. - float lower = 12.92 * x; - float upper = 1.055 * pow(x, 1.0f / 2.4f) - 0.055f; - - return mix(lower, upper, step(0.0031308f, x)); -} - void main() { color = texture(image, texcoord); diff --git a/kitty/blit_vertex.glsl b/kitty/blit_vertex.glsl index 89e1f7754..c1b8fc4da 100644 --- a/kitty/blit_vertex.glsl +++ b/kitty/blit_vertex.glsl @@ -1,4 +1,3 @@ -#version GLSL_VERSION #define left -1.0f #define top 1.0f #define right 1.0f diff --git a/kitty/border_fragment.glsl b/kitty/border_fragment.glsl index 87cc682a1..b770f9f99 100644 --- a/kitty/border_fragment.glsl +++ b/kitty/border_fragment.glsl @@ -1,4 +1,3 @@ -#version GLSL_VERSION in vec4 color; out vec4 final_color; diff --git a/kitty/border_vertex.glsl b/kitty/border_vertex.glsl index 71206d91b..6a14345a6 100644 --- a/kitty/border_vertex.glsl +++ b/kitty/border_vertex.glsl @@ -1,4 +1,5 @@ -#version GLSL_VERSION +#pragma kitty_include_shader + uniform uvec2 viewport; uniform uint colors[9]; uniform float background_opacity, do_srgb_correction; @@ -22,14 +23,6 @@ const uvec2 pos_map[] = uvec2[4]( uvec2(LEFT, TOP) ); -float linear2srgb(float x) { - // Linear to sRGB conversion. Needed to match alpha from the cell shader - float lower = 12.92 * x; - float upper = 1.055 * pow(x, 1.0f / 2.4f) - 0.055f; - - return mix(lower, upper, step(0.0031308f, x)); -} - float to_color(uint c) { return gamma_lut[c & FF]; } diff --git a/kitty/cell_fragment.glsl b/kitty/cell_fragment.glsl index 2d2bec92c..8ce592e21 100644 --- a/kitty/cell_fragment.glsl +++ b/kitty/cell_fragment.glsl @@ -1,4 +1,5 @@ -#version GLSL_VERSION +#pragma kitty_include_shader + #define {WHICH_PROGRAM} #define NOT_TRANSPARENT #define NO_FG_OVERRIDE @@ -39,22 +40,6 @@ in float colored_sprite; out vec4 final_color; // Util functions {{{ -float linear2srgb(float x) { - // Linear to sRGB conversion. - float lower = 12.92 * x; - float upper = 1.055 * pow(x, 1.0f / 2.4f) - 0.055f; - - return mix(lower, upper, step(0.0031308f, x)); -} - -float srgb2linear(float x) { - // sRGB to linear conversion - float lower = x / 12.92; - float upper = pow((x + 0.055f) / 1.055f, 2.4f); - - return mix(lower, upper, step(0.04045f, x)); -} - vec4 alpha_blend(vec4 over, vec4 under) { // Alpha blend two colors returning the resulting color pre-multiplied by its alpha // and its alpha. diff --git a/kitty/cell_vertex.glsl b/kitty/cell_vertex.glsl index 0eda08295..ca9a84af6 100644 --- a/kitty/cell_vertex.glsl +++ b/kitty/cell_vertex.glsl @@ -1,4 +1,3 @@ -#version GLSL_VERSION #extension GL_ARB_explicit_attrib_location : require #define {WHICH_PROGRAM} diff --git a/kitty/gl.c b/kitty/gl.c index c9d762272..28a99bec8 100644 --- a/kitty/gl.c +++ b/kitty/gl.c @@ -94,9 +94,9 @@ free_framebuffer(GLuint *fb_id) { static Program programs[64] = {{0}}; GLuint -compile_shader(GLenum shader_type, const char *source) { +compile_shaders(GLenum shader_type, GLsizei count, const GLchar * const * source) { GLuint shader_id = glCreateShader(shader_type); - glShaderSource(shader_id, 1, (const GLchar **)&source, NULL); + glShaderSource(shader_id, count, source, NULL); glCompileShader(shader_id); GLint ret = GL_FALSE; glGetShaderiv(shader_id, GL_COMPILE_STATUS, &ret); diff --git a/kitty/gl.h b/kitty/gl.h index fd6c0d74c..432b6643e 100644 --- a/kitty/gl.h +++ b/kitty/gl.h @@ -55,4 +55,4 @@ void bind_vertex_array(ssize_t vao_idx); void bind_vao_uniform_buffer(ssize_t vao_idx, size_t bufnum, GLuint block_index); void unbind_vertex_array(void); void unbind_program(void); -GLuint compile_shader(GLenum shader_type, const char *source); +GLuint compile_shaders(GLenum shader_type, GLsizei count, const GLchar * const * string); diff --git a/kitty/graphics_fragment.glsl b/kitty/graphics_fragment.glsl index 55617f018..709698868 100644 --- a/kitty/graphics_fragment.glsl +++ b/kitty/graphics_fragment.glsl @@ -1,4 +1,3 @@ -#version GLSL_VERSION #define ALPHA_TYPE uniform sampler2D image; diff --git a/kitty/graphics_vertex.glsl b/kitty/graphics_vertex.glsl index 999544974..3319f841a 100644 --- a/kitty/graphics_vertex.glsl +++ b/kitty/graphics_vertex.glsl @@ -1,4 +1,3 @@ -#version GLSL_VERSION #extension GL_ARB_explicit_attrib_location : require // Have to use fixed locations here as all variants of the program share the same VAO diff --git a/kitty/linear2srgb.glsl b/kitty/linear2srgb.glsl new file mode 100644 index 000000000..11efd10f5 --- /dev/null +++ b/kitty/linear2srgb.glsl @@ -0,0 +1,15 @@ +float srgb2linear(float x) { + // sRGB to linear conversion + float lower = x / 12.92; + float upper = pow((x + 0.055f) / 1.055f, 2.4f); + + return mix(lower, upper, step(0.04045f, x)); +} + +float linear2srgb(float x) { + // Linear to sRGB conversion. + float lower = 12.92 * x; + float upper = 1.055 * pow(x, 1.0f / 2.4f) - 0.055f; + + return mix(lower, upper, step(0.0031308f, x)); +} diff --git a/kitty/shaders.c b/kitty/shaders.c index f0611b807..a5cede318 100644 --- a/kitty/shaders.c +++ b/kitty/shaders.c @@ -1073,13 +1073,14 @@ draw_borders(ssize_t vao_idx, unsigned int num_border_rects, BorderRect *rect_bu static bool attach_shaders(PyObject *sources, GLuint program_id, GLenum shader_type) { + FREE_AFTER_FUNCTION const GLchar * * c_sources = calloc(sizeof(char*), PyTuple_GET_SIZE(sources)); for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(sources); i++) { PyObject *temp = PyTuple_GET_ITEM(sources, i); if (!PyUnicode_Check(temp)) { PyErr_SetString(PyExc_TypeError, "shaders must be strings"); return false; } - const char *vertex_shader = PyUnicode_AsUTF8(temp); - GLuint shader_id = compile_shader(shader_type, vertex_shader); - glAttachShader(program_id, shader_id); + c_sources[i] = PyUnicode_AsUTF8(temp); } + GLuint shader_id = compile_shaders(shader_type, PyTuple_GET_SIZE(sources), c_sources); + glAttachShader(program_id, shader_id); return true; } diff --git a/kitty/tint_fragment.glsl b/kitty/tint_fragment.glsl index ce3b849af..3f82c857e 100644 --- a/kitty/tint_fragment.glsl +++ b/kitty/tint_fragment.glsl @@ -1,5 +1,3 @@ -#version GLSL_VERSION - uniform vec4 tint_color; out vec4 color; diff --git a/kitty/tint_vertex.glsl b/kitty/tint_vertex.glsl index f8c85ece7..b8ad88a1d 100644 --- a/kitty/tint_vertex.glsl +++ b/kitty/tint_vertex.glsl @@ -1,4 +1,3 @@ -#version GLSL_VERSION uniform vec4 edges; diff --git a/kitty/utils.py b/kitty/utils.py index e70d92471..c7aba3c04 100644 --- a/kitty/utils.py +++ b/kitty/utils.py @@ -106,23 +106,27 @@ def platform_window_id(os_window_id: int) -> Optional[int]: def load_shaders(name: str, vertex_name: str = '', fragment_name: str = '') -> Tuple[Tuple[str, ...], Tuple[str, ...]]: from .fast_data_types import GLSL_VERSION - pat = re.compile(r'^#pragma kitty_include_shader <(.+?)>', re.MULTILINE) + pat = re.compile(r'^#pragma\s+kitty_include_shader\s+<(.+?)>', re.MULTILINE) - def load_source(name: str) -> str: - return read_kitty_resource(name).decode('utf-8').replace('GLSL_VERSION', str(GLSL_VERSION), 1) - - def load_sources(name: str) -> Tuple[str, ...]: - src = load_source(name) - ans: Tuple[str, ...] = src, + def load_sources(name: str, level: int = 0) -> Iterator[str]: + if level == 0: + yield f'#version {GLSL_VERSION}\n' + src = read_kitty_resource(name).decode('utf-8') + pos = 0 for m in pat.finditer(src): + prefix = src[pos:m.start()] + if prefix: + yield prefix iname = m.group(1) - ans += load_sources(iname) - return ans + yield from load_sources(iname, level+1) + pos = m.start() + if pos < len(src): + yield src[pos:] def load(which: str, lname: str = '') -> Tuple[str, ...]: lname = lname or name main = f'{lname}_{which}.glsl' - return load_sources(main) + return tuple(load_sources(main)) return load('vertex', vertex_name), load('fragment', fragment_name)