Skip to content

Commit 1798c52

Browse files
committed
Centralize the cell shader defines
1 parent ed08cba commit 1798c52

File tree

4 files changed

+80
-79
lines changed

4 files changed

+80
-79
lines changed

kitty/cell_defines.glsl

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#define PHASE_BOTH 1
2+
#define PHASE_BACKGROUND 2
3+
#define PHASE_SPECIAL 3
4+
#define PHASE_FOREGROUND 4
5+
6+
#define PHASE {WHICH_PHASE}
7+
#define HAS_TRANSPARENCY {TRANSPARENT}
8+
#define FG_OVERRIDE {FG_OVERRIDE}
9+
#define FG_OVERRIDE_THRESHOLD {FG_OVERRIDE_THRESHOLD}
10+
#define TEXT_NEW_GAMMA {TEXT_NEW_GAMMA}
11+
12+
#define DECORATION_SHIFT {DECORATION_SHIFT}
13+
#define REVERSE_SHIFT {REVERSE_SHIFT}
14+
#define STRIKE_SHIFT {STRIKE_SHIFT}
15+
#define DIM_SHIFT {DIM_SHIFT}
16+
#define MARK_SHIFT {MARK_SHIFT}
17+
#define MARK_MASK {MARK_MASK}
18+
#define USE_SELECTION_FG
19+
#define NUM_COLORS 256
20+
21+
#if (PHASE == PHASE_BOTH) || (PHASE == PHASE_BACKGROUND) || (PHASE == PHASE_SPECIAL)
22+
#define NEEDS_BACKROUND
23+
#endif
24+
25+
#if (PHASE == PHASE_BOTH) || (PHASE == PHASE_FOREGROUND)
26+
#define NEEDS_FOREGROUND
27+
#endif
28+
29+
#if (HAS_TRANSPARENCY == 1)
30+
#define TRANSPARENT
31+
#endif
32+
33+
#if defined(TRANSPARENT) || (PHASE == PHASE_SPECIAL)
34+
#define NEEDS_BG_ALPHA
35+
#endif

kitty/cell_fragment.glsl

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,11 @@
11
#pragma kitty_include_shader <alpha_blend.glsl>
22
#pragma kitty_include_shader <linear2srgb.glsl>
3-
4-
#define {WHICH_PROGRAM}
5-
#define NOT_TRANSPARENT
6-
#define NO_FG_OVERRIDE
7-
#define TEXT_NEW_GAMMA
8-
9-
#if defined(SIMPLE) || defined(BACKGROUND) || defined(SPECIAL)
10-
#define NEEDS_BACKROUND
11-
#endif
12-
13-
#if defined(SIMPLE) || defined(FOREGROUND)
14-
#define NEEDS_FOREGROUND
15-
#endif
3+
#pragma kitty_include_shader <cell_defines.glsl>
164

175
#ifdef NEEDS_BACKROUND
186
in vec3 background;
197
in float draw_bg;
20-
#if defined(TRANSPARENT) || defined(SPECIAL)
8+
#ifdef NEEDS_BG_ALPHA
219
in float bg_alpha;
2210
#endif
2311
#endif
@@ -53,8 +41,10 @@ vec4 vec4_premul(vec4 rgba) {
5341

5442
/*
5543
* Explanation of rendering:
56-
* There are a couple of cases, in order of increasing complexity:
57-
* 1) Simple -- this path is used when there are either no images, or all images are
44+
* There are two types of rendering, single pass and multi-pass. Multi-pass rendering is used when there
45+
* are images that are below the foreground. Single pass rendering has PHASE=PHASE_BOTH. Otherwise, there
46+
* are three passes, PHASE=PHASE_BACKGROUND, PHASE=PHASE_SPECIAL, PHASE=PHASE_FOREGROUND.
47+
* 1) Single pass -- this path is used when there are either no images, or all images are
5848
* drawn on top of text and the background is opaque. In this case, there is a single pass,
5949
* of this shader with cell foreground and background colors blended directly.
6050
* Expected output is a color premultiplied by alpha, with an alpha specified as well.
@@ -77,10 +67,9 @@ vec4 vec4_premul(vec4 rgba) {
7767
* 2b) Transparent bg with images
7868
* Same as (2a) except blending is done with PREMULT_BLEND and TRANSPARENT is defined in the shaders. background_opacity
7969
* is applied to default colored background cells in step (1).
80-
*
81-
* In this shader exactly *one* of SIMPLE, SPECIAL, FOREGROUND or BACKGROUND will be defined, corresponding
82-
* to the appropriate rendering pass from above.
8370
*/
71+
72+
// foreground functions {{{
8473
#ifdef NEEDS_FOREGROUND
8574
// sRGB luminance values
8675
const vec3 Y = vec3(0.2126, 0.7152, 0.0722);
@@ -92,12 +81,12 @@ float clamp_to_unit_float(float x) {
9281
return clamp(x, 0.0f, 1.0f);
9382
}
9483

95-
#ifdef FG_OVERRIDE
84+
#if (FG_OVERRIDE == 1)
9685
vec3 fg_override(float under_luminance, float over_lumininace, vec3 over) {
9786
// If the difference in luminance is too small,
9887
// force the foreground color to be black or white.
9988
float diff_luminance = abs(under_luminance - over_lumininace);
100-
float override_level = (1.f - colored_sprite) * step(diff_luminance, FG_OVERRIDE);
89+
float override_level = (1.f - colored_sprite) * step(diff_luminance, FG_OVERRIDE_THRESHOLD);
10190
float original_level = 1.f - override_level;
10291
return original_level * over + override_level * vec3(step(under_luminance, 0.5f));
10392
}
@@ -107,7 +96,7 @@ vec4 foreground_contrast(vec4 over, vec3 under) {
10796
float under_luminance = dot(under, Y);
10897
float over_lumininace = dot(over.rgb, Y);
10998

110-
#ifdef FG_OVERRIDE
99+
#if (FG_OVERRIDE == 1)
111100
over.rgb = fg_override(under_luminance, over_lumininace, over.rgb);
112101
#endif
113102

@@ -117,12 +106,12 @@ vec4 foreground_contrast(vec4 over, vec3 under) {
117106
return over;
118107
}
119108

120-
#ifdef TEXT_OLD_GAMMA
109+
#if (TEXT_NEW_GAMMA == 0)
121110
vec4 foreground_contrast_incorrect(vec4 over, vec3 under) {
122111
// Simulation of gamma-incorrect blending
123112
float under_luminance = dot(under, Y);
124113
float over_lumininace = dot(over.rgb, Y);
125-
#ifdef FG_OVERRIDE
114+
#if (FG_OVERRIDE == 1)
126115
over.rgb = fg_override(under_luminance, over_lumininace, over.rgb);
127116
#endif
128117
// This is the original gamma-incorrect rendering, it is the solution of the following equation:
@@ -156,14 +145,15 @@ vec4 calculate_premul_foreground_from_sprites(vec4 text_fg) {
156145
vec4 adjust_foreground_contrast_with_background(vec4 text_fg, vec3 bg) {
157146
// When rendering on a background we can adjust the alpha channel contrast
158147
// to improve legibility based on the source and destination colors
159-
#ifdef TEXT_OLD_GAMMA
148+
#if (TEXT_NEW_GAMMA == 0)
160149
return foreground_contrast_incorrect(text_fg, bg);
161150
#else
162151
return foreground_contrast(text_fg, bg);
163152
#endif
164153
}
165154

166155
#endif
156+
// end foreground functions }}}
167157

168158
float adjust_alpha_for_incorrect_blending_by_compositor(float text_fg_alpha, float final_alpha) {
169159
// Adjust the transparent alpha-channel to account for incorrect
@@ -179,7 +169,7 @@ float adjust_alpha_for_incorrect_blending_by_compositor(float text_fg_alpha, flo
179169
}
180170

181171
void main() {
182-
#ifdef SIMPLE
172+
#if (PHASE == PHASE_BOTH)
183173
vec4 text_fg = load_text_foreground_color();
184174
text_fg = adjust_foreground_contrast_with_background(text_fg, background);
185175
vec4 text_fg_premul = calculate_premul_foreground_from_sprites(text_fg);
@@ -191,23 +181,23 @@ void main() {
191181
#endif
192182
#endif
193183

194-
#ifdef SPECIAL
184+
#if (PHASE == PHASE_SPECIAL)
195185
#ifdef TRANSPARENT
196186
final_color = vec4_premul(background, bg_alpha);
197187
#else
198188
final_color = vec4(background, bg_alpha);
199189
#endif
200190
#endif
201191

202-
#ifdef BACKGROUND
192+
#if (PHASE == PHASE_BACKGROUND)
203193
#ifdef TRANSPARENT
204194
final_color = vec4_premul(background, bg_alpha);
205195
#else
206196
final_color = vec4(background, draw_bg);
207197
#endif
208198
#endif
209199

210-
#ifdef FOREGROUND
200+
#if (PHASE == PHASE_FOREGROUND)
211201
vec4 text_fg = load_text_foreground_color();
212202
vec4 text_fg_premul = calculate_premul_foreground_from_sprites(text_fg);
213203
final_color = text_fg_premul;

kitty/cell_vertex.glsl

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,7 @@
11
#extension GL_ARB_explicit_attrib_location : require
22
#pragma kitty_include_shader <srgb_gamma.glsl>
3+
#pragma kitty_include_shader <cell_defines.glsl>
34

4-
#define {WHICH_PROGRAM}
5-
#define NOT_TRANSPARENT
6-
#define DECORATION_SHIFT {DECORATION_SHIFT}
7-
#define REVERSE_SHIFT {REVERSE_SHIFT}
8-
#define STRIKE_SHIFT {STRIKE_SHIFT}
9-
#define DIM_SHIFT {DIM_SHIFT}
10-
#define MARK_SHIFT {MARK_SHIFT}
11-
#define MARK_MASK {MARK_MASK}
12-
#define USE_SELECTION_FG
13-
#define NUM_COLORS 256
145

156
// Inputs {{{
167
layout(std140) uniform CellRenderData {
@@ -23,7 +14,7 @@ layout(std140) uniform CellRenderData {
2314

2415
uint color_table[NUM_COLORS + MARK_MASK + MARK_MASK + 2];
2516
};
26-
#ifdef BACKGROUND
17+
#if (PHASE == PHASE_BACKGROUND)
2718
uniform uint draw_bg_bitfield;
2819
#endif
2920

@@ -43,18 +34,10 @@ const uvec2 cell_pos_map[] = uvec2[4](
4334
// }}}
4435

4536

46-
#if defined(SIMPLE) || defined(BACKGROUND) || defined(SPECIAL)
47-
#define NEEDS_BACKROUND
48-
#endif
49-
50-
#if defined(SIMPLE) || defined(FOREGROUND)
51-
#define NEEDS_FOREGROUND
52-
#endif
53-
5437
#ifdef NEEDS_BACKROUND
5538
out vec3 background;
5639
out float draw_bg;
57-
#if defined(TRANSPARENT) || defined(SPECIAL)
40+
#ifdef NEEDS_BG_ALPHA
5841
out float bg_alpha;
5942
#endif
6043
#endif
@@ -217,7 +200,7 @@ void main() {
217200
float cell_has_non_default_bg = step(1, float(abs(bg_as_uint - default_colors[1])));
218201
draw_bg = 1;
219202

220-
#if defined(BACKGROUND)
203+
#if (PHASE == PHASE_BACKGROUND)
221204
background = bg;
222205
// draw_bg_bitfield has bit 0 set to draw default bg cells and bit 1 set to draw non-default bg cells
223206
uint draw_bg_mask = uint(2 * cell_has_non_default_bg + (1 - cell_has_non_default_bg));
@@ -230,21 +213,21 @@ void main() {
230213
// On other cells it should be 1. For the SPECIAL program it should be 1 on cells with
231214
// selections/block cursor and 0 everywhere else.
232215
float is_special_cell = cell_has_block_cursor + float(is_selected & ONE);
233-
#ifndef SPECIAL
216+
#if (PHASE != PHASE_SPECIAL)
234217
is_special_cell += cell_has_non_default_bg + float(is_reversed);
235218
#endif
236219
bg_alpha = step(0.5, is_special_cell);
237-
#ifndef SPECIAL
220+
#if (PHASE != PHASE_SPECIAL)
238221
bg_alpha = bg_alpha + (1.0f - bg_alpha) * background_opacity;
239222
bg_alpha *= draw_bg;
240223
#endif
241224
#endif
242225

243-
#if defined(SPECIAL) || defined(SIMPLE)
226+
#if (PHASE == PHASE_SPECIAL) || (PHASE == PHASE_BOTH)
244227
// Selection and cursor
245228
bg = choose_color(float(is_selected & ONE), choose_color(use_cell_for_selection_bg, color_to_vec(fg_as_uint), color_to_vec(highlight_bg)), bg);
246229
background = choose_color(cell_has_block_cursor, color_to_vec(cursor_bg), bg);
247-
#if !defined(TRANSPARENT) && defined(SPECIAL)
230+
#if !defined(TRANSPARENT) && (PHASE == PHASE_SPECIAL)
248231
float is_special_cell = cell_has_block_cursor + float(is_selected & ONE);
249232
bg_alpha = step(0.5, is_special_cell);
250233
#endif

kitty/shaders.py

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import re
55
from functools import lru_cache, partial
66
from itertools import count
7-
from typing import Any, Callable, Dict, Iterator, Optional
7+
from typing import Any, Callable, Dict, Iterator, Optional, Set
88

99
from .constants import read_kitty_resource
1010
from .fast_data_types import (
@@ -53,16 +53,17 @@ def __init__(self, name: str, vertex_name: str = '', fragment_name: str = '') ->
5353
Program.include_pat = re.compile(r'^#pragma\s+kitty_include_shader\s+<(.+?)>', re.MULTILINE)
5454
self.vertex_name = vertex_name or f'{name}_vertex.glsl'
5555
self.fragment_name = fragment_name or f'{name}_fragment.glsl'
56-
self.original_vertex_sources = tuple(self._load_sources(self.vertex_name))
57-
self.original_fragment_sources = tuple(self._load_sources(self.fragment_name))
56+
self.original_vertex_sources = tuple(self._load_sources(self.vertex_name, set()))
57+
self.original_fragment_sources = tuple(self._load_sources(self.fragment_name, set()))
5858
self.vertex_sources = self.original_vertex_sources
5959
self.fragment_sources = self.original_fragment_sources
6060

61-
def _load_sources(self, name: str, level: int = 0) -> Iterator[str]:
61+
def _load_sources(self, name: str, seen: Set[str], level: int = 0) -> Iterator[str]:
6262
if level == 0:
6363
yield f'#version {GLSL_VERSION}\n'
64-
if name in self.filename_map:
64+
if name in seen:
6565
return
66+
seen.add(name)
6667
self.filename_map[name] = fnum = next(self.filename_number_counter)
6768
src = read_kitty_resource(name).decode('utf-8')
6869
pos = 0
@@ -74,7 +75,7 @@ def _load_sources(self, name: str, level: int = 0) -> Iterator[str]:
7475
yield f'\n#line {lnum} {fnum}\n{prefix}'
7576
lnum += prefix.count('\n')
7677
iname = m.group(1)
77-
yield from self._load_sources(iname, level+1)
78+
yield from self._load_sources(iname, seen, level+1)
7879
pos = m.end()
7980
if pos < len(src):
8081
yield f'\n#line {lnum} {fnum}\n{src[pos:]}'
@@ -161,32 +162,24 @@ def __call__(self, semi_transparent: bool = False, allow_recompile: bool = False
161162
STRIKE_SPRITE_INDEX=NUM_UNDERLINE_STYLES + 1,
162163
)
163164

164-
def resolve_cell_vertex_defines(which: str, v: str) -> str:
165-
self.cell_program_replacer.replacements['WHICH_PROGRAM'] = which
166-
v = self.cell_program_replacer(v)
167-
if semi_transparent:
168-
v = v.replace('#define NOT_TRANSPARENT', '#define TRANSPARENT')
169-
return v
170-
171-
def resolve_cell_fragment_defines(which: str, f: str) -> str:
172-
f = f.replace('{WHICH_PROGRAM}', which)
173-
if self.text_fg_override_threshold != 0.:
174-
f = f.replace('#define NO_FG_OVERRIDE', f'#define FG_OVERRIDE {self.text_fg_override_threshold}')
175-
if self.text_old_gamma:
176-
f = f.replace('#define TEXT_NEW_GAMMA', '#define TEXT_OLD_GAMMA')
177-
if semi_transparent:
178-
f = f.replace('#define NOT_TRANSPARENT', '#define TRANSPARENT')
179-
return f
165+
def resolve_cell_defines(which: str, src: str) -> str:
166+
r = self.cell_program_replacer.replacements
167+
r['WHICH_PHASE'] = f'PHASE_{which}'
168+
r['TRANSPARENT'] = '1' if semi_transparent else '0'
169+
r['FG_OVERRIDE_THRESHOLD'] = str(self.text_fg_override_threshold)
170+
r['FG_OVERRIDE'] = '1' if self.text_fg_override_threshold != 0. else '0'
171+
r['TEXT_NEW_GAMMA'] = '0' if self.text_old_gamma else '1'
172+
return self.cell_program_replacer(src)
180173

181174
for which, p in {
182-
'SIMPLE': CELL_PROGRAM,
175+
'BOTH': CELL_PROGRAM,
183176
'BACKGROUND': CELL_BG_PROGRAM,
184177
'SPECIAL': CELL_SPECIAL_PROGRAM,
185178
'FOREGROUND': CELL_FG_PROGRAM,
186179
}.items():
187180
cell.apply_to_sources(
188-
vertex=partial(resolve_cell_vertex_defines, which),
189-
frag=partial(resolve_cell_fragment_defines, which),
181+
vertex=partial(resolve_cell_defines, which),
182+
frag=partial(resolve_cell_defines, which),
190183
)
191184
cell.compile(p, allow_recompile)
192185

0 commit comments

Comments
 (0)