# Briefing — Nativer wgpu-2D-Renderer (parallele Instanz)

> Für die Instanz/den Agenten, der den nativen GPU-Renderer baut. Isoliert vom
> Web-Renderer; koordiniert über dieses Dokument.

## COMMIT-REGEL (verbindlich)
Dieses Repo darf **keinerlei Hinweise auf KI-Werkzeuge** enthalten — nicht im Code,
in Kommentaren oder in der Git-Historie. Keine `Co-Authored-By`-Trailer, keine
„Generated with"-Zeilen, keine Modell-/Agenten-Namen. Kommentare deutsch,
Identifier englisch. **Kein Commit ohne Ansage der Hauptinstanz.**

## 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 (die Hauptinstanz arbeitet dort an Features).
- Der Web-WebGL-Renderer bleibt bestehen (Browser-Lauffähigkeit + Referenz).
- Ergebnisse/Diffs zurückliefern; die Hauptinstanz committet und pflegt das Memory.

## 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).
