Custom shaders: Clear cached programs when disabling shaders

This commit is contained in:
白鸽 2026-09-14 22:41:26 +08:00
parent 7b41e33399
commit 18023eaafa
3 changed files with 25 additions and 1 deletions

View file

@ -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

View file

@ -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

View file

@ -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)