aboutsummaryrefslogtreecommitdiffstats
path: root/include/shader.h
blob: 05f8e57cdd9e2db0dabf6fd1731e69a0a8747a75 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/* Terminal shaders: per-cell colour computation over a pane's CONTENTS.
 *
 * A shader is a pure function from (cell, position, parameters) to that cell's
 * colours. It runs after pane_compose() has written the pane's viewport into
 * the screen and before the split guide is drawn over it, which is what makes
 * "contents, not chrome" fall out of the existing paint order rather than
 * needing a rule: the frame is painted before and lives outside the content
 * rect, and an affordance drawn after stays legible on top of a dimmed pane.
 *
 * Cells only. A shader may write fg, bg and attrs; it may not touch text, len
 * or width. Rewriting text would desync selection and copy (which read the
 * terminal, not the screen) and could break the wide-cell invariant.
 *
 * Each cell is shaded independently — no neighbours — so effects are limited
 * to what position and colour can express. That is most of them: tint, dim,
 * grayscale, gradients, vignettes, anything positional. Convolutions (blur,
 * bloom) would need a second buffer and are deliberately not possible here.
 *
 * Shaders chain: each is a complete pass, so `grayscale` then `tint` differs
 * from `tint` then `grayscale`, and both are expressible.
 */
#ifndef SLOSH_SHADER_H
#define SLOSH_SHADER_H

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

#include "shader_abi.h"
#include "slosh.h"

/* Per pane, and separately per config. Small and fixed: a stack this deep is
 * already a lot of passes over the same cells. */
#define SHADE_MAX 4
/* What one pane can end up running: the ones every pane gets from the config,
 * the ones attached to this pane, and the one or two the session derived for
 * this frame. */
#define SHADE_CHAIN_MAX (SHADE_MAX * 2 + 2)

/* shade_ctx_t, shader_t and shade_fn are the model (shader_abi.h). */

/* Build a shader by registry name. False if the name is not a built-in. */
bool shader_make(shader_t *out, const char *kind, color_t color,
                 uint8_t amount);
/* The same, for the shaders that take a number of their own. */
bool shader_make_p(shader_t *out, const char *kind, color_t color,
                   uint8_t amount, uint16_t param);
/* Iterate the registry: the i'th name, or NULL past the end. */
const char *shader_kind(size_t i);

/* Run `n` shaders in order over `r`, skipping the cells inside `hole` (NULL
 * for none). `base` supplies everything in the context except the per-cell
 * position and the size.
 *
 * The hole is what makes a pane's *frame* a rect: chrome is the pane's rect
 * minus its contents, and an effect has to see the whole frame's coordinates
 * or it could not travel round one — four separate passes over the four sides
 * would each start counting from zero. Skipped cells are not visited at all,
 * so a chrome pass cannot touch a cell the content pass owns. */
void shade_apply(screen_t *s, const shader_t *shaders, size_t n, rect_t r,
                 const rect_t *hole, const shade_ctx_t *base);

#endif /* SLOSH_SHADER_H */