Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
ed316fa
feat(webcam): add AI background cutout, blur, and custom wallpapers (…
EtienneLescot Aug 24, 2026
f02af18
fix(ci): update npmDepsHash in nix package and fix TypeScript types i…
EtienneLescot Aug 24, 2026
c0d032a
fix(nix): update npmDepsHash to match package-lock.json
EtienneLescot Aug 24, 2026
80b4235
fix(webcam): address the review findings on the AI background PR
EtienneLescot Aug 25, 2026
070efd8
docs(webcam): record where segmentation stands and what has to be mea…
EtienneLescot Aug 25, 2026
b8a18ad
docs(webcam): the workload is overhead-bound, so quantisation is the …
EtienneLescot Aug 25, 2026
45ee3c1
docs(webcam): E0 falsifies the overhead-bound reading — it is bandwid…
EtienneLescot Aug 25, 2026
de1ab5f
docs(webcam): round 3 brief — settle the execution provider
EtienneLescot Aug 25, 2026
0ed7a5e
docs(webcam): settle on the CPU execution provider
EtienneLescot Aug 25, 2026
8b1f51e
feat(webcam): composite the segmentation mask in the shader
EtienneLescot Aug 25, 2026
e766fb5
feat(webcam): vendor the ONNX segmentation model and its conversion s…
EtienneLescot Aug 25, 2026
673df34
feat(webcam): load the segmentation model and produce the mask
EtienneLescot Aug 25, 2026
b5f3a52
feat(webcam): extract the webcam frame and drive inference at 30 Hz
EtienneLescot Aug 25, 2026
942d58e
feat(webcam): drive segmentation from compose_frame
EtienneLescot Aug 25, 2026
dd7738c
feat(webcam): start segmentation from the scene, and prove it on the …
EtienneLescot Aug 25, 2026
3c8b5b8
feat(webcam): port the mask composite to Metal and WGSL
EtienneLescot Aug 26, 2026
07f39af
feat(webcam): move segmentation into the compositor and delete the re…
EtienneLescot Aug 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true },
"files": {
"ignoreUnknown": false,
"includes": ["**", "!**/*.css", "!**/design/**", "!**/.worktrees/**"]
"includes": ["**", "!**/*.css", "!**/design/**", "!**/.worktrees/**", "!**/public/mediapipe/**"]
},
"formatter": {
"enabled": true,
Expand Down
139 changes: 134 additions & 5 deletions crates/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions crates/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,26 @@ image = { version = "0.25", default-features = false, features = ["jpeg", "png"]
wgpu = { version = "24", features = ["wgsl"] }
pollster = "0.4"
cosmic-text = "0.19"
# Inference for the webcam segmentation mask. CPU execution provider only: measured on the
# target integrated GPU it costs +0.47 ms/frame against DirectML's +1.03, its cost does not
# scale with input resolution, and choosing it deletes the whole D3D11<->D3D12 interop
# (technical-documentation/engineering/webcam-segmentation.md).
#
# Behind the `segmentation` feature and OFF by default: `download-binaries` fetches the
# ONNX Runtime libs at build time, which is a packaging decision (nix, AUR, MS Store, CI)
# that has not been taken yet. The default build is unchanged.
# `load-dynamic` et NON `download-binaries` : ce dernier tire une build STATIQUE d'ONNX
# Runtime avec DirectML dedans (DirectML.lib, DXCORE.lib et les DmlOperator* apparaissent
# dans la ligne de lien) — exactement la dépendance que le choix de l'EP CPU sert à
# supprimer. En chargement dynamique, la lib est résolue à l'exécution, ce qui laisse le
# packaging la stager par plateforme comme il le fait déjà pour whisper-stt.
ort = { version = "2.0.0-rc.13", default-features = false, features = [
"std",
"ndarray",
"load-dynamic",
"api-27",
] }
ndarray = "0.16"

[workspace.dependencies.windows]
version = "0.58"
Expand Down
12 changes: 12 additions & 0 deletions crates/compositor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,20 @@ path = "src/lib.rs"
bindgen = "0.70"
cc = "1"

[features]
default = ["segmentation"]
# Segmentation IA de la webcam via ONNX Runtime (EP CPU).
#
# Activée par défaut, ce qui ne coûte rien au build : `ort` est lié en `load-dynamic`, donc
# aucune bibliothèque n'est nécessaire pour COMPILER. Elle l'est pour tourner — absente,
# `Segmenter::load` échoue, le compositeur écrit une ligne et dessine la webcam telle quelle.
# La désactiver reste possible pour une build qui ne veut pas du tout du code d'inférence.
segmentation = ["dep:ort", "dep:ndarray"]

[dependencies]
anyhow.workspace = true
ort = { workspace = true, optional = true }
ndarray = { workspace = true, optional = true }
serde.workspace = true
serde_json.workspace = true
image.workspace = true
Expand Down
14 changes: 14 additions & 0 deletions crates/compositor/src/compositor_linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,12 @@ impl Compositor {
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
count: None,
},
// Masque de segmentation du sujet webcam. TOUJOURS declare, meme sans
// masque : wgpu valide le bind group contre le layout, donc une entree
// absente ferait echouer chaque draw et pas seulement ceux qui l'utilisent.
// `dummy_view()` est lie a la place, et la branche du shader n'est de
// toute facon prise que si fx.z > 0.5.
tex_entry(4),
],
});
let pipeline_layout = gpu.device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
Expand Down Expand Up @@ -945,6 +951,14 @@ impl Compositor {
binding: 3,
resource: wgpu::BindingResource::Sampler(&self.sampler),
},
// Le portage Linux de la segmentation (capture + televersement du masque)
// n'est pas fait : on lie le dummy, ce qui laisse `fx.z` a 0 cote scene et
// donc la branche du shader jamais prise. Voir
// `technical-documentation/engineering/webcam-segmentation.md`.
wgpu::BindGroupEntry {
binding: 4,
resource: wgpu::BindingResource::TextureView(dummy),
},
],
});
(uniform, bind)
Expand Down
Loading