Files
DOSSIER-STANDALONE/docs/design/wgpu-2d-renderer-briefing.md
T

81 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Briefing — Nativer wgpu-2D-Renderer (parallele Instanz)
> Für den Entwickler, der den nativen GPU-Renderer baut. Isoliert vom
> Web-Renderer; koordiniert über dieses Dokument.
## COMMIT-REGEL (verbindlich)
Dieses Repo darf **keinerlei Fremd-Tool-Hinweise** enthalten — nicht im Code,
in Kommentaren oder in der Git-Historie. Kommentare deutsch, Identifier englisch.
**Kein Commit ohne Absprache.**
## Warum
Der 2D-Plan wird aktuell in einem WebGL-Canvas gerendert (Web-Stack). In Chromium
ist das 144-Hz-flüssig, aber **Tauris Linux-Webview = WebKitGTK bremst** (langsamer
Compositor, vermutlich 60-Hz-rAF-Cap). Bewiesen: dieselbe App im `chromium --app`-
Fenster = butterweich, im Tauri-Fenster = zäh — trotz imperativem Pan, CSS-transform-
Overlay, DMABUF-Tweaks. Siehe Memo `webkitgtk-bottleneck`.
**Lösung:** die schwere Grafik **nativ mit wgpu** rendern (Rust), die Webview macht
nur noch UI-Chrome (Panels/Buttons). So bleibt Tauri (natives Rust-Backend, winziges
Bundle) UND wir umgehen den Webview-Compositor komplett.
## Referenz-Implementierung (NICHT wegwerfen — 1:1 portierbar)
Der WebGL-Renderer unter `src/plan/glPlan/` ist die **arbeitende Referenz**. Die
harte Arbeit ist dort schon gelöst und portiert konzeptuell direkt nach wgpu:
- `glPlanCompile.ts`**Earcut-Triangulierung** (konkav-fähig), Linien→Quads mit
Normale+Seiten-Flag, Batch-Merging, Farb-Parsing. Unit-Tests: `glPlanCompile.test.ts`.
- `glPlanShaders.ts` — Vertex/Fragment (GLSL 300 es). **WGSL ≈ GLSL** — direkt übersetzbar.
- Füll-VS: Bildschirm-Position → Clip via `viewProj`-Matrix.
- Linien-VS: bildschirmkonstante bzw. papier-mm-Breite via Normalen-Offset im Clip
(siehe `strokeScale`/`strokePx`-Logik — Papier-mm × Massstab N × meet-Skala).
- `glPlanRender.ts` — Ortho-Matrix (aspekt-korrekt = SVG `xMidYMid meet`), Fill-/Line-
Pass, `computeOrthoMatrix`.
- Koordinaten-Konvention: BILDSCHIRM-Raum `sx = mx·PX_PER_M, sy = -my·PX_PER_M`
(`PX_PER_M=90`), Modell-Y hoch → Bildschirm-Y runter.
- Strichbreite = **echte Papier-mm im Massstab**: `Breite_px = mm · N/1000 · PX_PER_M ·
meetSkala` (repliziert SVG `printStrokeVb`). Am Beispiel 0.35 mm @ 1:100 = 0.35 mm.
Die **Daten** kommen aus `src/plan/generatePlan.ts` → `Plan.primitives` (Union-Typ
`Primitive`: polygon/line/arc/text). Text bleibt Overlay (nicht wgpu).
## Die EINE harte Frage (zuerst spiken/recherchieren)
**Wie rendert wgpu in das Tauri-Fenster neben der Webview?** Optionen recherchieren:
1. Natives Child-Surface unter der Webview (raw-window-handle), Webview transparent
drüber für UI-Chrome. Vermutlich der Zielweg.
2. Eigenes wgpu-Fenster (entkoppelt) — nur für den Spike, um Rendering von der
Fenster-Integration zu trennen.
3. wgpu→Textur→Webview — verwirft den Zweck (Copy-Overhead), nur Notnagel.
**Empfehlung:** Rendering-Spike ZUERST entkoppelt (Option 2, standalone `winit`+wgpu-
Fenster), das die `Primitive` als gefüllte Polygone + Striche zeichnet und Pan/Zoom
per Matrix-Uniform macht. Fenster-Integration in Tauri ist der zweite, separate Schritt.
## Meilensteine
- **M0 (Research):** kurzer Bericht `docs/design/wgpu-integration-findings.md` — wie
wgpu-Surface + Tauri/webview koexistieren (raw-window-handle, Transparenz, Z-Order,
Input-Routing). Quellen verlinken.
- **M1 (Rendering-Spike, standalone):** neue Crate `src-tauri/render2d/` (serde-Input
= geflachte Primitive), wgpu + WGSL:
- Earcut-Port (oder `lyon`/`earcutr` Crate evaluieren) → Dreiecke.
- Füll-Pipeline (gefüllte Polygone, Ortho-Matrix-Uniform).
- Linien-Pipeline (Quad-Expansion, echte Papier-mm-Breite).
- `cargo test` für die Tessellierung (Muster: `src-tauri/geometry` hat 4/4 Tests —
z. B. konkaves L flächentreu, wie `glPlanCompile.test.ts`).
- `cargo build` grün. (Visuelle Fenster-Verifikation braucht Display → an Mensch/
Display-Session übergeben; im Bericht vermerken.)
- **M2 (Tauri-Integration):** Surface unter die Webview, Pan/Zoom-Input aus der
Webview an den Renderer, Parität mit dem WebGL-Pfad messen (144 Hz).
- **M3:** Schraffur, Bögen, Auswahl-Highlight; danach 3D (three.js→wgpu).
## Koordination (WICHTIG)
- **Eigener Branch** (z. B. `feature/wgpu-renderer`), NICHT auf `master`/
`feature/parametric-walls` committen. Isolierter Worktree.
- **Nur** `src-tauri/` + neue Rust-Module + `docs/`. **NICHT** `src/App.tsx`,
`src/plan/*`, `types.ts` anfassen (dort laufen parallel Features).
- Der Web-WebGL-Renderer bleibt bestehen (Browser-Lauffähigkeit + Referenz).
- Ergebnisse/Diffs zurückliefern; Projektleitung committet.
## Gates
`cargo check`/`cargo test`/`cargo build` grün. Trace-Scan sauber (COMMIT-REGEL).
`npx tsc -b` + `npm run build` müssen unberührt grün bleiben (keine Web-Änderungen).