From 5263babc9a025eb41f1f1293d0d2ed44effc9926 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 31 Jan 2020 15:09:47 +0530 Subject: [PATCH] Use a single program for drawing background images --- kitty/bgimage_fragment.glsl | 18 ++---------------- kitty/bgimage_vertex.glsl | 27 ++++++++++++++++++++++++--- kitty/config_data.py | 3 --- kitty/shaders.c | 31 +++++++++++++++++++------------ kitty/state.c | 1 - kitty/state.h | 1 - kitty/window.py | 24 +++++++++--------------- 7 files changed, 54 insertions(+), 51 deletions(-) diff --git a/kitty/bgimage_fragment.glsl b/kitty/bgimage_fragment.glsl index 7256b0157..405784be5 100644 --- a/kitty/bgimage_fragment.glsl +++ b/kitty/bgimage_fragment.glsl @@ -1,25 +1,11 @@ #version GLSL_VERSION -#define LAYOUT_TYPE uniform sampler2D image; -uniform float bgimage_opacity; -#ifdef TILED -uniform float bgimage_scale; - -uniform float window_width; -uniform float window_height; -#endif +uniform float opacity; in vec2 texcoord; out vec4 color; void main() { -#ifdef TILED - ivec2 image_size = textureSize(image, 0); - vec2 txsz = vec2(window_width / (float(image_size[0]) * bgimage_scale), window_height / (float(image_size[1]) * bgimage_scale)); - color = texture(image, texcoord * txsz); -#endif -#ifdef SIMPLE color = texture(image, texcoord); -#endif - color = vec4(color.rgb, color.a * bgimage_opacity); + color = vec4(color.rgb, color.a * opacity); } diff --git a/kitty/bgimage_vertex.glsl b/kitty/bgimage_vertex.glsl index d28176a81..f31caac5e 100644 --- a/kitty/bgimage_vertex.glsl +++ b/kitty/bgimage_vertex.glsl @@ -3,6 +3,13 @@ #define top 1.0f #define right 1.0f #define bottom -1.0f +#define tex_left 0 +#define tex_top 0 +#define tex_right 1 +#define tex_bottom 1 + +uniform float tiled; +uniform vec4 sizes; // [ window_width, window_height, image_width, image_height ] out vec2 texcoord; @@ -12,10 +19,24 @@ const vec2 pos_map[] = vec2[4]( vec2(right, bottom), vec2(right, top) ); +const vec2 tex_map[] = vec2[4]( + vec2(tex_left, tex_top), + vec2(tex_left, tex_bottom), + vec2(tex_right, tex_bottom), + vec2(tex_right, tex_top) +); +float scale_factor(float window, float image) { + return max(1, window / image); +} + +float tiling_factor(int i) { + return tiled * scale_factor(sizes[i], sizes[i + 2]) + (1 - tiled); +} + void main() { - vec2 vertex = pos_map[gl_VertexID]; - texcoord = clamp(vec2(vertex[0], vertex[1]*-1), 0, 1); - gl_Position = vec4(vertex, 0, 1); + vec2 tex_coords = tex_map[gl_VertexID]; + texcoord = vec2(tex_coords[0] * tiling_factor(0), tex_coords[1] * tiling_factor(1)); + gl_Position = vec4(pos_map[gl_VertexID], 0, 1); } diff --git a/kitty/config_data.py b/kitty/config_data.py index 29ba40298..43bb46edd 100644 --- a/kitty/config_data.py +++ b/kitty/config_data.py @@ -867,9 +867,6 @@ Whether to tile or scale the background image.''')) o('background_image_linear', False, long_text=_(''' When background image is scaled, whether linear interpolation should be used.''')) -o('background_image_scale', 1.0, option_type=positive_float, long_text=_(''' -Only has an effect if :opt:`background_image_layout` is tiling, should be positive.''')) - o('dynamic_background_opacity', False, long_text=_(''' Allow changing of the :opt:`background_opacity` dynamically, using either keyboard shortcuts (:sc:`increase_background_opacity` and :sc:`decrease_background_opacity`) diff --git a/kitty/shaders.c b/kitty/shaders.c index db4e8fff4..168534178 100644 --- a/kitty/shaders.c +++ b/kitty/shaders.c @@ -9,7 +9,7 @@ #include "gl.h" #include -enum { CELL_PROGRAM, CELL_BG_PROGRAM, CELL_SPECIAL_PROGRAM, CELL_FG_PROGRAM, BORDERS_PROGRAM, GRAPHICS_PROGRAM, GRAPHICS_PREMULT_PROGRAM, GRAPHICS_ALPHA_MASK_PROGRAM, BLIT_PROGRAM, BGIMAGE_PROGRAM, BGIMAGE_TILED_PROGRAM, NUM_PROGRAMS }; +enum { CELL_PROGRAM, CELL_BG_PROGRAM, CELL_SPECIAL_PROGRAM, CELL_FG_PROGRAM, BORDERS_PROGRAM, GRAPHICS_PROGRAM, GRAPHICS_PREMULT_PROGRAM, GRAPHICS_ALPHA_MASK_PROGRAM, BLIT_PROGRAM, BGIMAGE_PROGRAM, NUM_PROGRAMS }; enum { SPRITE_MAP_UNIT, GRAPHICS_UNIT, BLIT_UNIT, BGIMAGE_UNIT }; // Sprites {{{ @@ -164,6 +164,10 @@ typedef struct { static CellProgramLayout cell_program_layouts[NUM_PROGRAMS]; static ssize_t blit_vertex_array; +typedef struct { + GLint image_location, tiled_location, sizes_location, opacity_location; +} BGImageProgramLayout; +static BGImageProgramLayout bgimage_program_layout = {0}; static void init_cell_program(void) { @@ -182,6 +186,10 @@ init_cell_program(void) { } #undef C blit_vertex_array = create_vao(); + bgimage_program_layout.image_location = get_uniform_location(BGIMAGE_PROGRAM, "image"); + bgimage_program_layout.opacity_location = get_uniform_location(BGIMAGE_PROGRAM, "opacity"); + bgimage_program_layout.sizes_location = get_uniform_location(BGIMAGE_PROGRAM, "sizes"); + bgimage_program_layout.tiled_location = get_uniform_location(BGIMAGE_PROGRAM, "tiled"); } #define CELL_BUFFERS enum { cell_data_buffer, selection_buffer, uniform_buffer }; @@ -334,25 +342,24 @@ cell_prepare_to_render(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen, GLfloa } static void -draw_bg(int program, OSWindow *w) { +draw_bg(OSWindow *w) { blank_canvas(w->is_semi_transparent ? OPT(background_opacity) : 1.0f, OPT(background)); - bind_program(program); + bind_program(BGIMAGE_PROGRAM); bind_vertex_array(blit_vertex_array); static bool bgimage_constants_set = false; if (!bgimage_constants_set) { - glUniform1i(glGetUniformLocation(program_id(program), "image"), BGIMAGE_UNIT); - glUniform1f(glGetUniformLocation(program_id(program), "bgimage_scale"), OPT(background_image_scale)); - glUniform1f(glGetUniformLocation(program_id(program), "bgimage_opacity"), OPT(background_opacity)); + glUniform1i(bgimage_program_layout.image_location, BGIMAGE_UNIT); + glUniform1f(bgimage_program_layout.opacity_location, OPT(background_opacity)); + GLfloat tiled = (OPT(background_image_layout) == TILING || OPT(background_image_layout) == MIRRORED) ? 1 : 0; + glUniform1f(bgimage_program_layout.tiled_location, tiled); bgimage_constants_set = true; } - glUniform1f(glGetUniformLocation(program_id(program), "height"), (float)(w->window_height)); - glUniform1f(glGetUniformLocation(program_id(program), "width"), (float)(w->window_width)); + glUniform4f(bgimage_program_layout.sizes_location, + (GLfloat)w->window_width, (GLfloat)w->window_height, (GLfloat)w->bgimage.width, (GLfloat)w->bgimage.height); glActiveTexture(GL_TEXTURE0 + BGIMAGE_UNIT); - glBindTexture(GL_TEXTURE_2D, w->bgimage.texture_id); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - unbind_vertex_array(); unbind_program(); } @@ -647,7 +654,7 @@ draw_borders(ssize_t vao_idx, unsigned int num_border_rects, BorderRect *rect_bu if (w->bgimage.texture_id) { glEnable(GL_BLEND); BLEND_ONTO_OPAQUE; - draw_bg((OPT(background_image_layout) == TILING || OPT(background_image_layout) == MIRRORED) ? BGIMAGE_TILED_PROGRAM : BGIMAGE_PROGRAM, w); + draw_bg(w); } if (num_border_rects) { @@ -769,7 +776,7 @@ static PyMethodDef module_methods[] = { bool init_shaders(PyObject *module) { #define C(x) if (PyModule_AddIntConstant(module, #x, x) != 0) { PyErr_NoMemory(); return false; } - C(CELL_PROGRAM); C(CELL_BG_PROGRAM); C(CELL_SPECIAL_PROGRAM); C(CELL_FG_PROGRAM); C(BORDERS_PROGRAM); C(GRAPHICS_PROGRAM); C(GRAPHICS_PREMULT_PROGRAM); C(GRAPHICS_ALPHA_MASK_PROGRAM); C(BLIT_PROGRAM); C(BGIMAGE_PROGRAM); C(BGIMAGE_TILED_PROGRAM); + C(CELL_PROGRAM); C(CELL_BG_PROGRAM); C(CELL_SPECIAL_PROGRAM); C(CELL_FG_PROGRAM); C(BORDERS_PROGRAM); C(GRAPHICS_PROGRAM); C(GRAPHICS_PREMULT_PROGRAM); C(GRAPHICS_ALPHA_MASK_PROGRAM); C(BLIT_PROGRAM); C(BGIMAGE_PROGRAM); C(GLSL_VERSION); C(GL_VERSION); C(GL_VENDOR); diff --git a/kitty/state.c b/kitty/state.c index c824a9a0a..c90059dd7 100644 --- a/kitty/state.c +++ b/kitty/state.c @@ -540,7 +540,6 @@ PYWRAP1(set_options) { S(cursor_blink_interval, parse_s_double_to_monotonic_t); S(cursor_stop_blinking_after, parse_s_double_to_monotonic_t); S(background_opacity, PyFloat_AsFloat); - S(background_image_scale, PyFloat_AsFloat); S(background_image_layout, bglayout); S(background_image_linear, PyObject_IsTrue); S(dim_opacity, PyFloat_AsFloat); diff --git a/kitty/state.h b/kitty/state.h index eee35ff9f..c37d87c4f 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -41,7 +41,6 @@ typedef struct { char* background_image; BackgroundImageLayout background_image_layout; - float background_image_scale; bool background_image_linear; bool dynamic_background_opacity; diff --git a/kitty/window.py b/kitty/window.py index cca10422d..7faf76dc1 100644 --- a/kitty/window.py +++ b/kitty/window.py @@ -15,14 +15,14 @@ from .constants import ( ScreenGeometry, WindowGeometry, appname, get_boss, wakeup ) from .fast_data_types import ( - BLIT_PROGRAM, BGIMAGE_PROGRAM, BGIMAGE_TILED_PROGRAM, CELL_BG_PROGRAM, - CELL_FG_PROGRAM, CELL_PROGRAM, CELL_SPECIAL_PROGRAM, CSI, DCS, DECORATION, - DIM, GRAPHICS_ALPHA_MASK_PROGRAM, GRAPHICS_PREMULT_PROGRAM, - GRAPHICS_PROGRAM, MARK, MARK_MASK, OSC, REVERSE, SCROLL_FULL, SCROLL_LINE, - SCROLL_PAGE, STRIKETHROUGH, Screen, add_window, cell_size_for_window, - compile_program, get_clipboard_string, init_cell_program, - set_clipboard_string, set_titlebar_color, set_window_render_data, - update_window_title, update_window_visibility, viewport_for_window + BGIMAGE_PROGRAM, BLIT_PROGRAM, CELL_BG_PROGRAM, CELL_FG_PROGRAM, + CELL_PROGRAM, CELL_SPECIAL_PROGRAM, CSI, DCS, DECORATION, DIM, + GRAPHICS_ALPHA_MASK_PROGRAM, GRAPHICS_PREMULT_PROGRAM, GRAPHICS_PROGRAM, + MARK, MARK_MASK, OSC, REVERSE, SCROLL_FULL, SCROLL_LINE, SCROLL_PAGE, + STRIKETHROUGH, Screen, add_window, cell_size_for_window, compile_program, + get_clipboard_string, init_cell_program, set_clipboard_string, + set_titlebar_color, set_window_render_data, update_window_title, + update_window_visibility, viewport_for_window ) from .keys import defines, extended_key_event, keyboard_mode_name from .rgb import to_color @@ -94,13 +94,7 @@ def load_shader_programs(semi_transparent=False): compile_program(p, v, ff) v, f = load_shaders('bgimage') - for which, p in { - 'SIMPLE': BGIMAGE_PROGRAM, - 'TILED': BGIMAGE_TILED_PROGRAM, - }.items(): - ff = f.replace('LAYOUT_TYPE', which) - compile_program(p, v, ff) - + compile_program(BGIMAGE_PROGRAM, v, f) init_cell_program()