diff --git a/kitty/glsl-uniforms.h b/kitty/glsl-uniforms.h index bfc5ebfe6..e34f6e15b 100644 --- a/kitty/glsl-uniforms.h +++ b/kitty/glsl-uniforms.h @@ -3,22 +3,35 @@ typedef struct BgimageUniforms { + int background; int image; + int positions; + int sizes; + int tiled; } BgimageUniforms; static inline void get_uniform_locations_bgimage(int program, BgimageUniforms *ans) { + ans->background = get_uniform_location(program, "background_0"); ans->image = get_uniform_location(program, "image_0"); + ans->positions = get_uniform_location(program, "positions_0"); + ans->sizes = get_uniform_location(program, "sizes_0"); + ans->tiled = get_uniform_location(program, "tiled_0"); } typedef struct BlitUniforms { + int dest_rect; int image; + int src_rect; } BlitUniforms; static inline void get_uniform_locations_blit(int program, BlitUniforms *ans) { + ans->dest_rect = get_uniform_location(program, "dest_rect_0"); ans->image = get_uniform_location(program, "image_0"); + ans->src_rect = get_uniform_location(program, "src_rect_0"); } typedef struct BorderUniforms { + int background_opacity; // Vertex Input locations int rect; int rect_color; @@ -30,6 +43,7 @@ typedef struct BorderUniforms { } BorderUniforms; static inline void get_uniform_locations_border(int program, BorderUniforms *ans) { + ans->background_opacity = get_uniform_location(program, "background_opacity_0"); ans->rect = 0; ans->rect_color = 1; ans->Colors.index = block_index(program, "block_Colors_0"); @@ -41,7 +55,10 @@ static inline void get_uniform_locations_border(int program, BorderUniforms *ans } typedef struct CellUniforms { + int draw_bg_bitfield; int sprites; + int text_contrast; + int text_gamma_adjustment; // Vertex Input locations int colors; int is_selected; @@ -55,7 +72,10 @@ typedef struct CellUniforms { } CellUniforms; static inline void get_uniform_locations_cell(int program, CellUniforms *ans) { + ans->draw_bg_bitfield = get_uniform_location(program, "draw_bg_bitfield_0"); ans->sprites = get_uniform_location(program, "sprites_0"); + ans->text_contrast = get_uniform_location(program, "text_contrast_0"); + ans->text_gamma_adjustment = get_uniform_location(program, "text_gamma_adjustment_0"); ans->colors = 0; ans->is_selected = 2; ans->sprite_idx = 1; @@ -70,35 +90,75 @@ static inline void get_uniform_locations_cell(int program, CellUniforms *ans) { } typedef struct GraphicsUniforms { + int amask_bg_premult; + int amask_fg; + int dest_rect; + int extra_alpha; int image; + int src_rect; } GraphicsUniforms; static inline void get_uniform_locations_graphics(int program, GraphicsUniforms *ans) { + ans->amask_bg_premult = get_uniform_location(program, "amask_bg_premult_0"); + ans->amask_fg = get_uniform_location(program, "amask_fg_0"); + ans->dest_rect = get_uniform_location(program, "dest_rect_0"); + ans->extra_alpha = get_uniform_location(program, "extra_alpha_0"); ans->image = get_uniform_location(program, "image_0"); + ans->src_rect = get_uniform_location(program, "src_rect_0"); } typedef struct Rounded_rectUniforms { + int background_color; + int color; + int params; + int rect; } Rounded_rectUniforms; static inline void get_uniform_locations_rounded_rect(int program, Rounded_rectUniforms *ans) { + ans->background_color = get_uniform_location(program, "background_color_0"); + ans->color = get_uniform_location(program, "color_0"); + ans->params = get_uniform_location(program, "params_0"); + ans->rect = get_uniform_location(program, "rect_0"); } typedef struct ScreenshotUniforms { + int dest_rect; int image; + int src_rect; + int src_size; } ScreenshotUniforms; static inline void get_uniform_locations_screenshot(int program, ScreenshotUniforms *ans) { + ans->dest_rect = get_uniform_location(program, "dest_rect_0"); ans->image = get_uniform_location(program, "image_0"); + ans->src_rect = get_uniform_location(program, "src_rect_0"); + ans->src_size = get_uniform_location(program, "src_size_0"); } typedef struct TintUniforms { + int edges; + int tint_color; } TintUniforms; static inline void get_uniform_locations_tint(int program, TintUniforms *ans) { + ans->edges = get_uniform_location(program, "edges_0"); + ans->tint_color = get_uniform_location(program, "tint_color_0"); } typedef struct TrailUniforms { + int cursor_edge_x; + int cursor_edge_y; + int trail_color; + int trail_opacity; + int x_coords; + int y_coords; } TrailUniforms; static inline void get_uniform_locations_trail(int program, TrailUniforms *ans) { + ans->cursor_edge_x = get_uniform_location(program, "cursor_edge_x_0"); + ans->cursor_edge_y = get_uniform_location(program, "cursor_edge_y_0"); + ans->trail_color = get_uniform_location(program, "trail_color_0"); + ans->trail_opacity = get_uniform_location(program, "trail_opacity_0"); + ans->x_coords = get_uniform_location(program, "x_coords_0"); + ans->y_coords = get_uniform_location(program, "y_coords_0"); } \ No newline at end of file diff --git a/kitty/shaders/slang.py b/kitty/shaders/slang.py index 5613ee7eb..4a990c817 100644 --- a/kitty/shaders/slang.py +++ b/kitty/shaders/slang.py @@ -17,11 +17,17 @@ from functools import lru_cache from itertools import chain, product from pathlib import Path from types import MappingProxyType -from typing import Any, Callable, Iterable, Iterator, NamedTuple +from typing import Any, Callable, Iterable, Iterator, Literal, NamedTuple from kitty.constants import read_kitty_resource, shaders_dir, slangc from kitty.fast_data_types import ( + BGIMAGE_PROGRAM, BLINK, + BLIT_PROGRAM, + BORDERS_PROGRAM, + CELL_BG_PROGRAM, + CELL_FG_PROGRAM, + CELL_PROGRAM, COLOR_IS_INDEX, COLOR_IS_RGB, COLOR_IS_SPECIAL, @@ -30,10 +36,20 @@ from kitty.fast_data_types import ( DECORATION_MASK, DIM, GLSL_VERSION, + GRAPHICS_ALPHA_MASK_PROGRAM, + GRAPHICS_PREMULT_PROGRAM, + GRAPHICS_PROGRAM, MARK, MARK_MASK, REVERSE, + ROUNDED_RECT_PROGRAM, + SCREENSHOT_PROGRAM, STRIKETHROUGH, + TINT_PROGRAM, + TRAIL_PROGRAM, + compile_program, + get_options, + init_cell_program, ) from kitty.options.types import Options, defaults @@ -134,6 +150,76 @@ def variant_name(variant: dict[str, str], default: dict[str, str]) -> str: return key.hexdigest()[:5] +def glsl_shaders(name: str, variant_name: str = '') -> tuple[str, str]: + if variant_name: + variant_name = '.' + variant_name + with open(os.path.join(shaders_dir, f'{name}{variant_name}.vert.glsl')) as f: + vert = f.read() + with open(os.path.join(shaders_dir, f'{name}{variant_name}.frag.glsl')) as f: + frag = f.read() + return vert, frag + + +class LoadShaderPrograms: + + text_fg_override_threshold: tuple[float, Literal['%', 'ratio']] = 0, '%' + text_old_gamma: bool = False + + opts: Options | None = None + + def get_options(self) -> Options: + try: + return self.opts or get_options() + except RuntimeError: + return defaults + + @property + def needs_recompile(self) -> bool: + opts = self.get_options() + return ( + bool(opts.text_fg_override_threshold[0]) != bool(self.text_fg_override_threshold[0]) or + opts.text_fg_override_threshold[1] != self.text_fg_override_threshold[1] or + (opts.text_composition_strategy == 'legacy') != self.text_old_gamma + ) + + def recompile_if_needed(self) -> None: + if self.needs_recompile: + self(allow_recompile=True) + + def __call__(self, allow_recompile: bool = False) -> None: + default_cell_variant = cell_variant() + opts = self.get_options() + self.text_old_gamma = opts.text_composition_strategy == 'legacy' + self.text_fg_override_threshold = opts.text_fg_override_threshold + for prog, (only_fg, only_bg) in { + CELL_PROGRAM: (False, False), CELL_FG_PROGRAM: (True, False), CELL_BG_PROGRAM: (False, True), + }.items(): + v = cell_variant(opts, only_fg=only_fg, only_bg=only_bg) + vert, frag = glsl_shaders('cell', variant_name(v, default_cell_variant)) + compile_program(prog, (vert,), (frag,), allow_recompile) + for prog, vname in { + GRAPHICS_PROGRAM: '', GRAPHICS_ALPHA_MASK_PROGRAM: 'alpha_mask', + GRAPHICS_PREMULT_PROGRAM: 'premult', + }.items(): + vert, frag = glsl_shaders('graphics', vname) + compile_program(prog, (vert,), (frag,), allow_recompile) + for name, prog in { + 'bgimage': BGIMAGE_PROGRAM, + 'tint': TINT_PROGRAM, + 'trail': TRAIL_PROGRAM, + 'blit': BLIT_PROGRAM, + 'screenshot': SCREENSHOT_PROGRAM, + 'rounded_rect': ROUNDED_RECT_PROGRAM, + 'border': BORDERS_PROGRAM, + }.items(): + vert, frag = glsl_shaders(name) + compile_program(prog, (vert,), (frag,), allow_recompile) + init_cell_program() + + +load_shader_programs = LoadShaderPrograms() + + class SlangFile(NamedTuple): path: str = '' text: str = ''