Commit Graph

2 Commits

Author SHA1 Message Date
Vantz Stockwell
a2770d3edf perf: double-buffered RDP frames + frontend rAF throttling
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 4m20s
Root cause: RDP was unresponsive due to frame pipeline bottleneck.
- get_frame() held tokio::Mutex while cloning 8.3MB, blocking the
  RDP session thread from writing new frames (mutex contention)
- Frontend fetched on every backend event with no coalescing
- Every GraphicsUpdate emitted an IPC event, flooding the frontend

Fix:
- Double-buffer: back_buffer (tokio::Mutex, write path) and
  front_buffer (std::sync::RwLock, read path) — reads never block writes
- get_frame() now synchronous, reads from front_buffer via RwLock
- Backend throttles frame events to every other GraphicsUpdate
- Frontend coalesces events via requestAnimationFrame
- RdpView props now reactive (computed) for correct resize behavior
- rdp_get_frame command no longer async (no .await needed)
- screenshot_png_base64 no longer async

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 09:19:40 -04:00
Vantz Stockwell
c75da74ecd feat: Phase 4 complete — RDP via ironrdp
Rust RDP service: ironrdp client with full connection handshake
(TCP -> TLS -> CredSSP -> NLA), pixel buffer frame delivery,
mouse/keyboard input via scancode mapping, graceful disconnect.
Runs in dedicated thread with own tokio runtime to avoid Send
lifetime issues with ironrdp trait objects.

Vue frontend: RdpView canvas renderer with 30fps polling,
mouse/keyboard capture, RdpToolbar with Ctrl+Alt+Del and
clipboard. SessionContainer handles both SSH and RDP tabs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 16:05:11 -04:00