diff --git a/docs/changelog.rst b/docs/changelog.rst index 85d91e2ce..048ecb3a0 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -206,7 +206,7 @@ Detailed list of changes - Custom shaders: Allow tinting inactive windows toward a configurable color, preserving the tab bar and active window padding. Support static effects - without periodic redraws. + without periodic redraws, and fix re-enabling a previously disabled shader. - Various throughput performance improvements for a 15-35% real world improvement depending on workload diff --git a/kitty/shaders/slang.py b/kitty/shaders/slang.py index b0a97017a..72e258538 100644 --- a/kitty/shaders/slang.py +++ b/kitty/shaders/slang.py @@ -274,6 +274,7 @@ class LoadShaderPrograms: slot_pipelines = pmap.get(slot) if not slot_pipelines: compile_program(prog, (), (), {}, allow_recompile) + self.last_built_custom_shaders.pop(prog, None) else: try: pipeline = merge_pipelines(slot_pipelines) @@ -283,6 +284,7 @@ class LoadShaderPrograms: except Exception as e: log_error(f'Failed to build custom shader for slot {slot} with error: {e}') compile_program(prog, (), (), {}, allow_recompile) + self.last_built_custom_shaders.pop(prog, None) else: try: if self.last_built_custom_shaders.get(prog) != (vert, frag, metadata): @@ -291,6 +293,7 @@ class LoadShaderPrograms: except Exception as e: log_error(f'Failed to load custom shader for slot {slot} with error: {e}') compile_program(prog, (), (), {}, allow_recompile) + self.last_built_custom_shaders.pop(prog, None) do(CUSTOM_END_PROGRAM, 'end') compile_program(-2, (), (), {}) # initialize programs diff --git a/kitty_tests/slang.py b/kitty_tests/slang.py index 41948dab0..360863371 100644 --- a/kitty_tests/slang.py +++ b/kitty_tests/slang.py @@ -8,10 +8,12 @@ import os import shutil import subprocess import tempfile +from unittest.mock import patch from kitty.constants import slangc from kitty.shaders.slang import ( EntryPoint, + LoadShaderPrograms, SlangFile, Stage, build_custom_shader_pipeline_glsl, @@ -62,6 +64,25 @@ class TestSlang(BaseTest): self.assertTrue(fragment) self.ae(metadata['pipeline']['groups'][0]['animation_step'], 0) + def test_custom_shader_reenable(self): + from kitty.fast_data_types import CUSTOM_END_PROGRAM + from kitty.options.types import defaults + + loader = LoadShaderPrograms() + loader.last_built_custom_shaders = {} + pipeline = parse_pipeline_definition(['startgroup', 'animation_step 0', 'shaders focus-highlight', 'endgroup'], 'test') + self.ae(pipeline['groups'][0]['animation_step'], 0) + with ( + patch('kitty.shaders.slang.parse_pipeline', return_value=pipeline), + patch('kitty.shaders.slang.build_custom_shader_pipeline_glsl', return_value=('vertex', 'fragment', {})), + patch('kitty.shaders.slang.compile_program') as compile_program, + ): + for shaders in (('test',), (), ('test',)): + loader.opts = defaults._replace(custom_shaders=shaders) + loader.compile_custom_shaders(allow_recompile=True) + operations = [c.args[1] for c in compile_program.call_args_list if c.args[0] == CUSTOM_END_PROGRAM] + self.ae(operations, [('vertex',), (), ('vertex',)]) + def test_slang_parser(self): def check(src: str, expected: SlangFile) -> None: actual = parse_slang_text(src)