The Vulkan render+present ran inside the 16ms glib timeout on the GTK
main thread — the same thread WebKit uses for overlay input — and FIFO
presents plus vkAcquireNextImageKHR (100ms timeout) blocked it for a
large slice of every frame, which made the React player overlay laggy
compared to the OpenGL path (which just draws into GTK's own FBO).
Windows and macOS already render on a dedicated thread; Linux now does
too. The GTK loop only publishes the surface size through atomics and
keeps the GDK/Wayland surface handles.
Also:
- prefer VK_PRESENT_MODE_MAILBOX_KHR when available so presents don't
block on vsync at all
- take the player_renderer lock only around the mpv render itself, not
across acquire/present, so overlay IPC (seek, status polls) no longer
queues behind vsync waits
- on X11, create the Vulkan surface on a private XOpenDisplay connection;
GTK never calls XInitThreads, so presenting over GTK's Display from
another thread would race
- a load issued before the render thread has wired mpv's Vulkan render
context is now deferred and retried instead of failing
Adds selectable Vulkan (Linux/macOS/Windows) and D3D11 (Windows,
HDR-capable) rendering paths alongside the existing OpenGL mpv
surface, wired through mpv's native render API, plus a Wayland
subsurface helper for Linux compositing and a settings toggle to
pick the backend.
Frame interpolation could never engage: vo_libmpv answers no
VOCTRL_GET_DISPLAY_FPS and vsync estimation only accumulates once
display-sync is already active, so with the render API
video-sync=display-resample silently reverts unless the client sets
display-fps-override. Set a 60 FPS baseline at renderer init and
override it with the real monitor refresh rate (GDK monitor on Linux,
GetDeviceCaps VREFRESH on Windows); mpv refines it further from
report_swap timing. Turning interpolation off now also resets
video-sync back to audio.
Anime4K: drop the //!WHEN OUTPUT > 1.2x gates from the bundled shaders
(they made the shader a no-op whenever the window wasn't upscaling by
more than 1.2x) and deliver glsl-shaders changes via change-list
commands. Verified against the bundled libmpv fork with a headless
EGL harness: shader set/clr visibly changes rendered pixels and
display-sync-active flips to yes once an fps override exists.
player_init now creates the mpv renderer even when a native surface is
used, so the first session's player_apply_preferences no longer lands
on a missing renderer and gets dropped. Async mpv command failures are
logged from MPV_EVENT_COMMAND_REPLY instead of vanishing.
Chapter-derived intro/outro segments (used when IntroDB/AniSkip return
nothing) can now be disabled; the pref reaches the player through
player_apply_preferences on every load.
Also fixes autoSkipSegments: the frontend sent it but the command never
accepted it and playback info never returned it, so auto-skip was
silently always off.
Replace the MyAnimeList integration with AniList OAuth and per-profile
anime tracking sync (animeDetection, animeExternalSync,
anilistExternalSync), wired through effectRunner/libraryEffects and the
Account settings section.
Add anime upscaling (bundled Anime4K shaders, auto mode keyed off
detected anime playback) and frame interpolation prefs, passed to mpv
via player options.
Replace AMOLED mode with a gif-autoplay pref backed by a gif_to_webm
ffmpeg conversion command. Assorted UI work: virtualized
CollectionShelfRow, mark-watched flow in ContinueWatchingRow, sync
service popovers, Nuvio token refresh, DELETE support in nuvio_request.
Bump typescript to 6.0, vite 8.1.1, lucide-react 1.22; enable
fluxa_core desktop feature.
Playback itself now works on Linux, but the React controls overlay
doesn't appear. nativePlayerActive only flips on the native-player-show
Tauri event, so log both sides: whether Rust actually emits it, and
whether the App.tsx listener is registered in time to receive it.
- Render backend now sources prebuilt libmpv from KhooLy/mpv (gpu-next),
fetched via src-tauri/fetch-libmpv.sh; video-sync switched to
display-resample with vsync-paced render loops on all platforms.
- CI (build.yml) updated to fetch the fork instead of building/bundling
mpv per-platform.
- Fix: next-episode auto-skip countdown kept ticking while paused.
- Fix: addon HTTP fetches had no timeout, so a hung (not just refused)
connection could block the home feed load forever, leaving a blank
screen with no error.
- Fix: Nuvio offline banner overlapped the player's top bar instead of
pushing it down.
- Add F11 as a fullscreen toggle in the player, alongside F.
- Restyle Skip Intro/Outro button: flat surface instead of native
button chrome bleeding through, icon, hover/focus state, progress bar.