f4cd16b7ac
Spawns a GTK-free winit window with its own wgpu surface from Tauri's setup hook on a background thread, sidestepping the WebKitGTK surface contention on Wayland. Reuses render2d's renderer via a shared demo module. Opt-in behind the native2d cargo feature; default build unaffected.
91 lines
4.9 KiB
Markdown
91 lines
4.9 KiB
Markdown
# M2 — nativer wgpu-2D-Renderer im Tauri-Fenster: Ansatzwahl
|
|
|
|
> Ziel: den bereits fluessig laufenden standalone `render2d`-Renderer aus dem
|
|
> ECHTEN Tauri-Prozess heraus mit nativer GPU-Performance anzeigen — nicht in der
|
|
> WebKitGTK-Webview (Perf-Flaschenhals), nicht in einem Chromium-Workaround.
|
|
> Maschine: Linux, Wayland, AMD.
|
|
|
|
## Gewaehlter Ansatz: **B — separates natives Fenster (winit) im Tauri-Prozess**
|
|
|
|
Der Tauri-Hauptthread haelt weiterhin die GTK-Hauptschleife + das Webview-Fenster
|
|
(HTML-Chrome). Aus dem Tauri-`setup`-Hook startet der Prozess auf einem
|
|
Hintergrund-Thread ein **eigenes natives winit-Fenster** mit eigener wgpu-Surface,
|
|
das die `render2d`-Demo-Szene (konkaves L + Raum + Papier-mm-Linien) rendert,
|
|
pan-/zoombar. Renderer/Szene werden NICHT reimplementiert — es ist exakt der Code
|
|
des verifizierten standalone `spike`-Bins (`render2d::gpu::Renderer` +
|
|
`render2d::demo_scene`).
|
|
|
|
### Warum B (und was gegen A/C spricht)
|
|
|
|
- **Kein geteilter Wayland-Surface → keine Contention/Flicker.** winit spricht auf
|
|
Linux DIREKT Wayland/X11 (Crates `wayland-client`/`x11rb`), es benutzt **kein
|
|
GTK**. Das native Fenster bekommt eine eigene, von WebKitGTK voellig getrennte
|
|
Wayland-Surface. Genau das umgeht das dokumentierte Problem aus der Vorrecherche
|
|
(Roh-wgpu-Surface UNTER der Webview im selben Fenster → Flicker/Schwarzbild auf
|
|
Wayland).
|
|
- **Zwei Fenster-Stacks, aber KEIN Event-Loop-Konflikt.** tao (Tauri) fuehrt eine
|
|
GTK-Hauptschleife auf dem Hauptthread; winit fuehrt eine eigene Schleife.
|
|
winit 0.30 erlaubt die Event-Loop explizit auf einem Nicht-Haupt-Thread via
|
|
`EventLoopBuilderExtWayland::with_any_thread(true)` (X11-Pendant analog). Der
|
|
native Renderer laeuft daher auf `std::thread` „cad-native2d", der Tauri-/GTK-
|
|
Hauptthread bleibt frei. Da winit nicht an GTK gebunden ist, kollidieren die
|
|
beiden Schleifen nicht (getrennte Stacks, getrennte fds).
|
|
|
|
- **Ansatz A (wgpu-Surface im SELBEN Tauri-Fenster, Unter-/Overlay):** verworfen.
|
|
taos `raw_window_handle_rwh_06()` liefert auf Wayland den `WaylandWindowHandle`
|
|
der GTK-`ApplicationWindow` — also DIESELBE Surface, in die WebKitGTK
|
|
komponiert. Eine zweite wgpu-Surface darauf ist genau die Contention, die die
|
|
Vorrecherche als flackernd/schwarz auf diesem Setup markiert hat. Hoechstes
|
|
Wayland-Risiko, fuer den Spike ungeeignet.
|
|
- **Ansatz C (wgpu als Haupt-Surface, HTML nur duennes Overlay):** verworfen fuer
|
|
den Spike. Sauberste Perf-Story, aber groesster Umbau: die ganze App muesste auf
|
|
eine winit/tao-getriebene Haupt-Schleife umziehen und die Tauri-Webview zur
|
|
Nebenrolle degradiert werden. Kein „minimaler realer Spike" mehr. Bleibt die
|
|
Ziel-Endarchitektur-Option, aber nach B.
|
|
|
|
## Crates / Versionen (verifiziert aus der Lock-Datei)
|
|
|
|
| Rolle | Crate | Version |
|
|
|---|---|---|
|
|
| Tauri | `tauri` / `tauri-runtime-wry` | 2.11.5 / 2.11.4 |
|
|
| Fenster (Webview-Seite) | `tao` | 0.35.3 |
|
|
| Webview | `wry` | 0.55.1 |
|
|
| Natives Renderfenster | `winit` | 0.30.13 |
|
|
| GPU | `wgpu` / `wgpu-hal` | 22.1.0 / 22.0.0 |
|
|
| Handle-Bruecke | `raw-window-handle` | **0.6.2 (identisch fuer tao UND wgpu/winit)** |
|
|
| Renderer | `render2d` (Pfad) | 0.1.0, Feature `window` |
|
|
|
|
Der entscheidende Kompatibilitaets-Glueckstreffer: tao 0.35 und wgpu 22/winit 0.30
|
|
teilen sich `raw-window-handle 0.6.2` — keine rwh-Versionsbruecke noetig. (Fuer
|
|
Ansatz B wird der tao-Handle gar nicht gebraucht, weil das native Fenster eine
|
|
eigene winit-Surface hat; die Versions-Parität ist aber die Voraussetzung fuer ein
|
|
spaeteres A/Compositing, falls je gewuenscht.)
|
|
|
|
## Wayland-Caveats (fuer den Start auf dieser Maschine)
|
|
|
|
- **`WEBKIT_DISABLE_DMABUF_RENDERER=1`** bleibt fuer die Webview-Sichtbarkeit auf
|
|
diesem Wayland/AMD-Setup noetig (Vorrecherche). Betrifft die WebKitGTK-Seite,
|
|
nicht das wgpu-Fenster.
|
|
- Das native winit-Fenster laeuft ueber Vulkan; GLES/EGL-Fallback wurde standalone
|
|
ebenfalls funktionierend gesehen. `WGPU_BACKEND=gl` erzwingt bei Vulkan-Zicken
|
|
den GL-Pfad.
|
|
- `with_any_thread(true)` ist zwingend — ohne die Freigabe panict winit, weil es
|
|
die Event-Loop sonst nur auf dem Hauptthread zulaesst (den haelt hier GTK).
|
|
|
|
## Bau-Isolierung
|
|
|
|
Alles hinter Cargo-Feature **`native2d`** in `cad-tauri` (opt-in). Der normale
|
|
Build (`cargo build`, `npm run tauri:dev`) zieht weder winit noch wgpu und bleibt
|
|
unveraendert. `render2d` bleibt ohne Tauri-/GTK-Abhaengigkeiten headless baubar
|
|
und testbar.
|
|
|
|
## Naechster Schritt Richtung Vollbild-App (2D-Viewport + HTML-Chrome)
|
|
|
|
1. Szene aus dem echten Modell speisen: `Plan.primitives` (TS) → serde-`Scene` →
|
|
ueber einen Tauri-`emit`/Command an den native2d-Thread (statt `demo_scene`).
|
|
2. Pan/Zoom-State zwischen Webview-Chrome und native2d-Fenster synchronisieren
|
|
(Tauri-Events beidseitig).
|
|
3. Fenster-Kopplung: das native Fenster als Kind/als angedockten Bereich neben der
|
|
Webview positionieren (Layout), spaeter ggf. Umstieg auf Ansatz C, wenn ein
|
|
einziges Fenster gefordert ist.
|