mirror of
https://github.com/Droid-Deck/DroidDeck.git
synced 2026-11-12 11:31:08 +00:00
ci/python-tests-on-workstation-runner
48
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2848484a99 |
feat: fuck proot and proots mama (#2300)
* feat: experimental native userland that runs the Linux side without proot * fix(native): keep the visible name of link2symlink binaries * fix(ci): run the native hook build through bash * fix(native): address review findings in the hook and the ctl fallback * fix(ctl): use the broadcast fallback only when content is missing * fix(native): survive Android's seccomp filter in ld.so, libc and posix_spawn children * docs(native): how to test under Android's seccomp filter * fix(session): hide an unlistable /sys/bus/pci/devices so libpci does not abort Chromium's GPU init * fix(native): nested syscall() redirects no longer loop with libblsession's openat2 * fix(native): controllers reach Steam and the install-script evaluator no longer blocks game moves * fix(native): write the hook's NUL character literals as escapes * fix(native): proot fast path turns off and greys out while running without proot * fix(native): D-Bus logins work and Xwayland still admits root once peers read as root * fix(native): scripts on session mounts outside the rootfs run with the rootfs shell * fix(native): games on the SD card library start in their own folder * fix(native): Wine drive links proot made point at their real places * fix(native): at-calls, uid lookups and relative programs follow the session's mounts * fix(native): close-from in spawned programs covers what is open at the spawn * fix(native): service names resolve and the DNS fallback answers what was asked * build(native): the hook is built with its Go support and tracked by the preload recipe * fix(native): drive links into identity mounts stay, and relink and seccomp patch failures are logged * fix(native): seccomp-sim's filter holds every allowed call * fix(ctl): the broadcast fallback only stands in for a missing content command * fix(native): pre-2.33 glibc stat calls present owners as root too * fix(native): res_init and res_ninit call glibc, so Steam's store resolves names * fix(ci): a preload lock older than a new output rebuilds that group, and generated headers are not hashed * fix(native): a second seccomp patch run leaves other system calls alone * fix(native): the terminal and bottom desktop keep proot's environment in a native session * fix(native): any number of session mounts, and openat2 relative to a mounted folder * fix(agent): a native command's stdin is written beside its timeout * fix(ctl): native rejects --env without = and timeouts outside 0-600 s * fix(native): the resolver fallback has the network's IPv6 servers, and lookups keep the fallback's validation errors * fix(native): a spawn whose dup2 source close-from closed fails with EBADF * fix(native): __getcwd_chk checks its buffer, and seccomp-sim -a takes only call numbers * feat(native): guests see the session hostname from uname and gethostname * feat(native): the terminal and bottom desktop run without proot * fix(components): an origin APK without a newer preload output still proves the rest * fix(native): seccomp-sim -a rejects empty fields * fix(native): gethostbyname no longer answers failed lookups with Ubuntu and Debian addresses * feat(native): store installers, root helpers, Comet and Xodus run without proot * fix(native): the hook finds libraries, preloads and itself through a sandbox's mounts, and ldconfig -C makes its cache * feat(native): Flatpak sandboxes run without proot, and apply_extra runs without a runtime * fix(native): remove, glob and nftw take guest paths, and links in a mount are followed as the guest sees them * fix(native): Flatpak sandboxes get the session's mounts, their libraries' RUNPATHs, and no rootfs-only settings * fix(native): gethostbyname asks the network's DNS servers, nftw of / gives single slashes, and the library path fits mapped directories * fix(native): a native process starts in its working directory's real place * fix(native): the library path given to ld.so holds whole directories only * fix(native): Wine drive links keep their guest paths, so proot finds the library after a native session * fix(native): droiddeckctl native prepares the rootfs with the setting off * fix(native): a SysV segment stays while any process has it attached * fix(native): DNS lookups ask the network's own servers before public ones * fix(native): a program's own seccomp traps reach its own SIGSYS handler * feat(native): run native sessions under a device's own app seccomp filter for testing * fix(native): SysV attaches and collection take a lock, a failed mark fails the attach, and collection closes its directory * fix(native): shmat fails when it cannot take the segment lock * fix(native): the SysV segment lock is retried when a signal interrupts it * fix(native): process tools see the session's processes as root's * fix(native): native processes are named after their program, not ld.so * fix(native): a session's helpers keep the mode the session started in * fix(native): a keyed SysV segment stays until IPC_RMID * fix(native): a rootfs link to an absolute guest path is followed in the guest, so Wine finds its z: drive * fix(native): a sandbox whose loader can't be patched runs under proot * fix(native): creating a private SysV segment also collects stale ones * fix(native): a session stopped during startup forgets its mode * fix(xbox): a native backend is authorized by its process ancestry * fix(native): Wine's drive links are followed in the guest from any prefix * fix(native): only the startup that owns the running session publishes its mode * fix(native): a SysV segment stays until IPC_RMID even after its maker ends * fix(native): a sandbox mount nested in another mount gets its own place * fix(native): a sandbox whose mount places can't be made runs under proot |
||
|
|
3c96df4ab1 |
feat(ubisoft): Ubisoft Connect store with native sign-in, library, downloads and launch (#2322)
* feat(ubisoft): sign in to Ubisoft Connect and list the owned library * feat(ubisoft): download games natively through Demux and Ubisoft's CDN * fix(ubisoft): show the owned games on the store page * fix(ctl): reach the agent bridge by broadcast when the shell has no content command * feat(ubisoft): run Ubisoft games in one prefix with Ubisoft Connect installed and the game registered * feat(ubisoft): launch games through a native stand-in for Ubisoft Connect's local service * feat(ubisoft): document the launcher pipes, log why owned games have no download, drop the installer after extraction * feat(ubisoft): Steam-owned Ubisoft games install through Steam, and the launch session carries the game's application id * feat(ubisoft): answer Denuvo activations through Ubisoft's activation service and log unanswered pipe traffic * feat(ubisoft): report installed chunks to the game and skip add-ons the account does not own * fix(ubisoft): the overlay stays off, Ubisoft's install steps pick Windows components, and shared-prefix games keep their own settings * fix(ubisoft): write the manifest's registry values, and pick the game's exe over Ubisoft's installer stubs * fix(ubisoft): stream download slices, guard the launch hook, and keep per-game components in the shared prefix * fix(ubisoft): direct launches in the shared prefix keep their own game id * ci(ubisoft): build the launcher service after the prepared components are verified * fix(ubisoft): verify reused files, drop syncs from a signed-out account, and clear activation requests before launch * fix(ubisoft): fetch again a reused file whose slices cannot be checked |
||
|
+1 |
3733c50902 |
feat: non-Adreno graphics stack (Venus, open driver pairs, gamescope patches) (#2029)
* Retain compositor resources when GPU completion is unconfirmed * Stop quarantined GPU callers before retries and mapped writes * Support Android hardware-buffer presentation over Wayland * Support PowerVR swapchains and linear image imports in Gamescope * Bundle verified PowerVR graphics components through existing build preparation * Detect and select the system Vulkan backend on PowerVR * Apply PowerVR Steam and game compatibility during normal launches * Show PowerVR support through existing driver and component controls * Update existing hardware guidance for system Vulkan support * Import the shared system Vulkan readiness check * Discover and propagate the actual PowerVR render node * Prune obsolete PowerVR runtimes after guest processes exit * Retain external DMA-BUF ownership after GPU quarantine * Name the PowerVR HAL selection explicitly * Isolate component UI tests from application startup * Cover the inherited FEX preset in PowerVR profile tests * Log test worker failures for CI diagnosis * Remove temporary test logging after diagnostic CI * Prefer system dependencies for the Android Vulkan loader * Capture raw stderr before test worker termination * Remove the temporary test worker crash probe * Import pinned DXVK recipe prerequisite from PowerVR PR570 Copy only the standalone build recipe, source pin, BC-format prerequisite and presentation-sync patch/check from wallentx/DroidDeck at |
||
|
|
430af5e22d |
feat: desktop and scrolling wall live wallpapers (#2012)
* feat: desktop and scrolling wall live wallpapers selectable from Android settings * fix: render the wall wallpaper off the main thread and give it its own thumbnail * fix: serialize wall wallpaper visibility and wait out in-flight draws on surface destroy * fix: restart the wall loop on surface recreation and keep queued visibility changes * fix: keep the wall loop alive across a failed canvas lock and finish redraws before returning * fix: post the wall redraw asynchronously on surface change * fix: redraw the desktop wallpaper logo from the real mark and show game covers on the wall * chore: mount the git dir in build containers and seed new worktrees from the main checkout * fix: decode wall covers as RGB_565 and seed worktree assets only into empty dirs * feat: drop the desktop wallpaper and add frame rate and speed settings to the wall * feat: wall settings over the live wallpaper with a match-screen rate, and drop the center vignette * perf: pace the wall on vsync and draw it on a hardware canvas * fix: stage worktree seed copies and publish them only after they succeed * fix: point the wall settings link at the activity class so the picker shows the gear * fix: dedupe wall covers by app and space repeats like the in-app wall, keep the frame loop alive across surface gaps * fix: show the picker preview behind wall settings and drop the display-rate lookup * fix: stop wall frame callbacks when the surface goes and only replace an empty seed destination * fix: skip a seed when the destination reappears before the staged copy is moved in |
||
|
|
8171bf20fd | Merge latest origin/main and resolve conflicts | ||
|
|
c5577478ca |
chore: remove source comments and unused code, translate every missing string (#1965)
* chore(i18n): translate every missing string in all locales Adds the 87 strings the bottom-screen Dashboard and in-game stats pages introduced to all 32 locales, plus the 51 older settings strings Japanese and the 50 Chinese locales were still missing. Every locale now has all 3456 translatable strings with the same placeholders as English. Also translates 36 entries that were still English where the language does not use the English word, and makes es-419 touch_app_id use the same %1$s placeholder as English. * chore(patches): drop comments from the lines downstream patches add Removes comment lines and trailing comments from lines our patches add, with hunk headers recounted. Lines that a later patch uses as context and the upstream backport 0123 are left as they are. The gamescope, FEX, proot and xodus series still apply to their pinned sources, and the patched trees differ only in those comments. test_hud_frames now finds the HUD writer by its first declaration. * docs: credit Greenlight, Better xCloud, viture-v2, GameNative and DiRTTelemetryErrorFix These were credited only in source headers and NOTICE files. * chore: remove source comments and unused functions Removes explanatory comments from first-party Kotlin, Java, C, C++, Rust, TypeScript, Python, shell, Gradle, CMake and workflow files. License and attribution headers stay, and vendored third-party trees, generated files and license files are untouched. A shellcheck directive is kept, and udevmon's fallthrough comments became fallthrough attributes. Syntax trees and token streams match the previous sources apart from the comments and Python docstrings. Module docstrings that argparse prints are kept, and device-smoke.sh prints the same --help text from a heredoc. Also removes 37 functions and 4 fields that nothing referenced. * chore: remove comments from the Syncthing integration and the latest main sources * docs: credit Syncthing and the syncthing-android fork * chore(i18n): translate the Syncthing strings in all locales The 107 strings the Syncthing integration added are now in all 32 locales. sync_web_path_locked names the Syncthing tab by its label. * docs: credit @xXJSONDeruloXx for the HUD metric readers The CPU, GPU load, thermal and battery readers come from their PerformanceHudView pull requests #777, #877, #991, #1406 and #1573. The FusionHUD credit line is unchanged. * docs: credit the HUD metric readers to @xXJSONDeruloXx's work |
||
|
|
8cb5c2168e |
feat(hud): GPU load and clock without root where Android blocks kgsl (#1969)
On some Adreno devices (the Retroid Pocket Duo) SELinux hides kgsl's sysfs nodes from apps, so the HUD showed no GPU % and no GPU clock. Devices whose nodes are readable keep using them; nothing changes there or on GPUs without kgsl. Where the nodes are blocked: - GPU %: a native reader maps kgsl's memstore read-only (any kgsl client may) and samples the ringbuffer start/end timestamps once a millisecond while a HUD is shown. That covers all GPU work, Android's own composition included. - Backup for GPU %: an implicit Vulkan layer in the guest (tools/gpuload) and the compositor time their own GPU work with timestamp queries. It runs until the memstore stamps are seen moving, and for the whole session if they never move. - GPU clock: a small GPU job of our own reads the always-on and RBBM cycle counters (libgpuclock). The HUD diagnostics export lists which source each GPU value came from. tools/gpuload/build.sh takes the Vulkan headers from build_local.sh's NDK first and keeps NDK paths with spaces intact. |
||
|
|
8c09b2c6a8 | Intergrated syncthing (#1442) | ||
|
|
0a5955d6fa |
Merge remote-tracking branch 'droiddeck/main' into feat/malibridge
# Conflicts: # README.md # app/src/main/java/com/droiddeck/launcher/gpu/TurnipDriver.java # app/src/main/java/com/droiddeck/launcher/runtime/BwrapSpawner.kt # app/src/main/res/values-ar/strings.xml # app/src/main/res/values-b+es+419/strings.xml # app/src/main/res/values-bg/strings.xml # app/src/main/res/values-cs/strings.xml # app/src/main/res/values-da/strings.xml # app/src/main/res/values-de/strings.xml # app/src/main/res/values-el/strings.xml # app/src/main/res/values-es/strings.xml # app/src/main/res/values-fi/strings.xml # app/src/main/res/values-fr/strings.xml # app/src/main/res/values-hi/strings.xml # app/src/main/res/values-hu/strings.xml # app/src/main/res/values-in/strings.xml # app/src/main/res/values-it/strings.xml # app/src/main/res/values-ja/strings.xml # app/src/main/res/values-ko/strings.xml # app/src/main/res/values-ms/strings.xml # app/src/main/res/values-nb/strings.xml # app/src/main/res/values-nl/strings.xml # app/src/main/res/values-pl/strings.xml # app/src/main/res/values-pt-rPT/strings.xml # app/src/main/res/values-pt/strings.xml # app/src/main/res/values-ro/strings.xml # app/src/main/res/values-ru/strings.xml # app/src/main/res/values-sv/strings.xml # app/src/main/res/values-th/strings.xml # app/src/main/res/values-tr/strings.xml # app/src/main/res/values-uk/strings.xml # app/src/main/res/values-vi/strings.xml # app/src/main/res/values-zh-rCN/strings.xml # app/src/main/res/values-zh-rHK/strings.xml # app/src/main/res/values-zh-rTW/strings.xml # app/src/main/res/values/strings.xml # tools/linuxfs/overlay/usr/local/bin/droiddeck-game-env |
||
|
|
0516d023fa |
feat: art-first library cards with a display menu (#1744)
* feat: art-first library cards with a display menu for size, title and storage * build: use native arm64 docker on Apple Silicon and add a fast deploy loop * fix: address review feedback on library cards and local build scripts |
||
|
|
27bdc68867 | ci: faster pipeline and fewer network flakes (#1719) | ||
|
|
a69ce00b6a |
Build and package the Mali bridge from external/MaliBridge
The server is built with the NDK into libvkbridge_server.so (a program the app execs from its native library directory); the Linux ICD, its manifest and the self-test go into the runtime assets with the other glibc preloads, locally and in CI. |
||
|
|
99136ea23b | Add support for Java 17 via mise (#1231) | ||
|
|
e9891d5a29 |
feat: Remote Play host: PipeWire capture, hardware encoding, touch and game audio (#1139)
* feat: run SteamOS PipeWire and WirePlumber for gamescope screen capture * feat: hardware Remote Play encoding through MediaCodec behind Steam's V4L2 stage * feat: deliver Remote Play touches to gamescope as touches * feat: route game audio through PulseAudio while a Remote Play client is connected * fix: keep the Remote Play marker when a forked child closes the encoder * fix: allow standalone preload tests without V4L2 encoder hook |
||
|
|
e3246b7dd5 |
feat: ship proot, DirectAudio, Xbox, Comet and hand tracking as CI-built add-on packs (#1198)
* perf: download hand tracking models and native libs on first use * feat: build and publish add-on packs in CI, add Xbox and Comet packs * feat: ship proot and DirectAudio drivers as CI-built packs * test: hand tracking readiness requires the tracking pack * ci: attach PR test-build packs to the PR release instead of Components |
||
|
|
a63f3b1fbc | Add experimental Xbox and PC Game Pass store support (#1156) | ||
|
|
48adf4d1ff | perf: local builds reuse unchanged native steps across runs and worktrees (#819) | ||
|
|
aecd2ebe1d | cleanup (#764) | ||
|
|
f4b0ab6867 |
feat: Cardboard VR mode with ARM64 SteamVR (#704)
* feat: add Cardboard mode with side-by-side lens-distorted eyes and 3DoF head tracking * fix: derive the Cardboard field of view from the panel and recentre fully when far from upright * feat: share the Cardboard head pose with the guest and add a SteamVR driver for it * feat: run SteamVR's compositor on Turnip/KGSL with a display-extension layer and a driver-direct HMD * feat: show SteamVR frames in Cardboard mode through a driver-side presenter and a fake direct-mode display * feat: install and start SteamVR for Cardboard mode from the session drawer * docs: describe Cardboard mode and the SteamVR path * feat: drive SteamVR hands from the game pad and keep the Cardboard headset out of standby * docs: record where the SteamVR dashboard stops * fix: map Cardboard head tracking to the screen's axes and keep turns about the real vertical as yaw * fix: give Cardboard its previous picture back when SteamVR stops * fix: report sem_otime from emulated SysV semaphores so SteamVR's web helper can start * fix: bridge SteamVR's shared semaphores across processes and keep Steam alive while SteamVR runs * feat: present SteamVR straight to DroidDeck's compositor at panel resolution * docs: update Cardboard VR notes for the dashboard, semaphore bridge and direct presenter * fix: keep Wine and FEX signal handlers in the VR layer; add semaphore tracing * fix: clear a stale SteamVR active marker on status * fix: clear only an old SteamVR active marker * fix: unblock SteamVR clients on Turnip and keep Steam's web helper alive across SteamVR runs * fix: judge shared waits before a submit's own signals and on Vulkan 1.0 devices * docs: record VR games, SteamVR Home and OpenXR results on the Thor * docs: add Cardboard VR learnings from the Thor bring-up * docs: add Cardboard VR screenshots from the Thor * fix: keep the VR layer's display stand-in to SteamVR runs and clear a leftover marker at session start * fix: report SteamVR start and stop failures from the helper's exit code |
||
|
|
6c35297dba | Add Quest 3/3S compatibility to the standard APK (#642) | ||
|
|
8f36eb7f54 | Add opt-in GOG achievements through Comet (#651) | ||
|
|
513ae84612 | chore(): Fix the MacOS build process locally. (#637) | ||
|
|
a6d15bcd0b |
Expanded Fastpaths for proot and increased performance up to 57% (#494)
* perf: fast path resolves links, /proc and glue as proot does, and answers uname, isatty and passwd
The fast path handed back to proot whatever crossed a symlink, /proc or a directory proot
only shows as glue, which is most of what Steam and Wine ask. It now walks a path the way
proot's canonicalize() does, so those calls stay in-process:
- links are followed in guest terms and their text detranslated as detranslate_path() does,
including readlink into a buffer the kernel cut short and /proc's exe, cwd and fd links;
- a binding proot dropped at start is dropped here too, glue above a binding is ENOENT, and a
last component proot cannot stat is left to the kernel;
- pipe and socket dirfds are ENOTDIR, rmdir("dir/") removes dir, and "." and ".." go to proot;
- a blocking accept() with a connection already waiting no longer goes to proot.
Also answered: uname() and gethostname() (proot's utsname never changes), isatty() (glibc
2.43 asks with TCGETS2, which proot rewrites) and getpwnam/getpwuid when nsswitch.conf
sends passwd to files first and the entry is there (Xwayland asks for every client).
equiv.py, equiv2.py and equiv3.py match line for line with and without the fast path
(222, 507 and 924 lines). Per call on the RedMagic: realpath 240 us -> 1.0 us,
realpath /proc/self/fd/N 408 -> 9.9, getpwuid 41.5 -> 4.6, uname 28 -> 0.006.
* perf: LD_AUDIT module skips library lookups proot would fail
ld.so looks each library up along the game's search path, and Proton puts the game's
directory, Steam's runtime and video directories and its own library directories ahead of
/usr/lib: 72% of ld.so's opens in an Among Us launch failed, each a round trip to proot.
libblaudit.so answers la_objsearch() for a candidate proot would certainly fail with ENOENT
(its directory walked as canonicalize() walks it, the name or a directory on the way missing).
It has no libc and maps the fast path's trampoline itself. Each lookup's first candidate is
still opened, since a skipped one fails with ld.so's errno as it stands, and the default
directories are never skipped, so dlerror() reads the same. droiddeck-proton and the extra
wrapper add it to LD_AUDIT when the fast path is on.
* perf: droiddeck-proton checks a tool's components with one sha256sum
Each program the launcher starts pays a dozen traced library lookups under the game's search
path before it does anything. One sha256sum over every listed file replaces one per file;
the check itself is unchanged.
* perf: build a locale archive for C.UTF-8
Every program loads the locale LANG names before main(). glibc ships C.UTF-8 as a directory
it looks for once per category under two spellings, before reading gconv's module lists:
about 30 opens, each a stop in proot, in every process of the session. droiddeck-session
builds /usr/lib/locale/locale-archive (and gconv's cache) once per glibc package, so that is
one open.
localedef names a finished archive by hard link, which Android refuses; with
DROIDDECK_LINK_RENAME=1 libblsession turns a refused link into a rename that will not replace
an existing name.
* perf: library beat starts its helpers only when what they read changed
Every 15 s the session ran droiddeck-seed-redists (some forty programs under proot) and, when
a library directory had changed, steam-compatibility: a burst of thousands of proot stops each
quarter minute, game loads included. The seeder now runs when a library changed or a prefix
(or Proton's template for them) is unmarked, the compat pass when a manifest, depot, tool or
config.vdf changed, both checked from bash without starting anything, and each every five
minutes regardless. The seeder reads its stamp and the time without a subshell each.
* perf: fakeinput opens pad.log on its first line
Every process the library is loaded in opened the session's pad.log at start, a stop in proot
on shared storage, and most never write to it. The file is now opened when there is a line to
write.
* docs: the fast path as it ships, the audit module and measured launch times
* fix: a game the app launches after an idle spell comes to the front
The Steam client brings a game it launched forward only while it counts someone as present,
which it reads from gamescope's input counter. A game the app launched after four or more
minutes without a touch started, mapped its window, and stayed behind the library page until
the next input (device: Palworld, Stardew Valley, Fallout: New Vegas, Mortal Kombat X; the same
on main). The session now watches a requested launch, and when the game's window is focusable
but the interface keeps focus for two polls, counts one input on gamescope's counter, as a key
would. Nothing changes for a launch the client already brings forward.
|
||
|
|
d99ed8e00b | fix(desktop): address KDE feedback and keep local builds in sync with CI (#488) | ||
|
|
e99d5f9505 |
Stores: GOG, Epic Games and Amazon Games libraries, installs and cloud saves (#476)
A Stores section (rail, under Games; Setup › Stores gate) with each store's sign-in, library, storefront shelves and a download queue. Each store has two tabs, Store and Library, and Library filters to All or Installed; libraries open from a saved copy and refresh in the background, with install sizes on every card. Games install to internal storage, or a card chosen at Install time, and are registered in the Steam client as non-Steam games, so they launch through Steam and droiddeck-proton from either the front end or the client. - Downloads: GOG, Epic and Amazon engines in Rust (app/src/main/rust/stores, built by cargo-ndk, nothing compiled in the tree). One adaptive fetch core with a latency brake, stalled-host handoff and every CDN a store offers. Per-stage progress, pause/resume, two-step cancel that deletes, failed downloads kept for retry, a foreground service with Wi-Fi and wake locks and notification controls. - Games tab: store source chips (Steam, GOG, Epic, Amazon, Custom) and store art. - Epic: per-launch exchange code from the app and from Steam's Play button, "Epic sign-in (EOS)", "Launch offline", and a game's web links opened in Android's browser for EOS consent. The EOS overlay crashed games and is left out. - Cloud saves (GOG, Epic): pulled before launch, pushed after the game or the session ends, no upload before a first download, conflicts never overwritten, backups both ways. - Logs: every store line redacted; the engine log goes to daily files. |
||
|
|
fe71084f23 |
feat: replace the LXQt desktop with SteamOS-style KDE Plasma (#473)
* feat: replace the LXQt desktop with SteamOS-style KDE Plasma * feat: leaving the KDE desktop logs out through Plasma and returns to gaming mode * feat: DroidDeck logo wallpaper as the KDE desktop default * feat: build the KDE wallpaper from the DroidDeck mark artwork * ci: keep the built desktop package as a short-lived artifact for device testing * fix: the desktop loading screen no longer promises Steam on the desktop * docs: the output resize comments name the desktop's KWin * fix: the desktop package verifies every package's Arch Linux ARM signature and never replaces a published tag * fix: programs sent to the GPU from the desktop drop its software rendering overrides * fix: an interrupted desktop install no longer counts as installed * feat: pin the desktop package to its DroidDeck-Components release instead of the catalog |
||
|
|
789b603022 |
DirectAudio from its own release: driver set per Proton interface (CachyOS fix), the Steam client's own DirectAudio sink, binaries out of tree (#439)
DirectAudio from its own release: driver set per Proton audio interface (CachyOS fix), the Steam client's own DirectAudio sink, binaries out of tree Games - Two driver sets ship from the pinned DirectAudio release (tools/directaudio/release.env = directaudio-linux-v1.1.0, sha256-checked by tools/directaudio/fetch.sh in CI and build_local.sh): linux-wine11 for Valve Proton 11 / Experimental / GE-Proton, and linux-wine11-systhread for Proton-CachyOS, whose Wine carries the system-thread mmdevapi interface. steam-compatibility picks by whether the Proton's own winepulse.so imports PsCreateSystemThread, never by the version string (both say wine-11.0; the wrong set is silence). No matching set: DirectAudio off, Proton's audio runs, logged. - Proton-CachyOS's launcher pre-sets WINE_AUDIO_DRIVER=pulse,alsa and its mmdevapi reads that before the registry (Valve's and GE's do not read it): the wrapper exports WINE_AUDIO_DRIVER=directaudio,pulse as well as writing the registry. On CachyOS this also makes DirectAudio engage on a game's first launch. - A wineserver from an earlier Steam verb can save its in-memory registry over the appended Audio value; the wrapper says so when one is live. Writing through it (wine reg add) and creating a missing prefix first (proton run wineboot) were tried on the device and withdrawn: a second Proton/Wine run inside Steam's launch sequence got launches aborted. - Tests: both sets, no set, no prefix (34 pass). Steam client audio - DirectAudio = module-directaudio-native-sink, the game driver's AAudio engine inside the PulseAudio daemon, one step from Android (adaptive buffer, two-burst floor, primed ring with fades, reopen on route change, watchdog, limiter). Default. Shared output = the previous relay route, kept. New pref clientAudioRoute; the old boolean is not read. If the native sink cannot open its stream the daemon keeps running (.nofail) and ensureClientSink loads the plain AAudio sink instead, logged to audio.log. Audio bundle stamp bumped. Out of tree - app/src/main/assets/directaudio/ is generated and ignored; tools/directaudio-relay/ and the vendored module-directaudio-sink.c + da_relay_proto.h are gone; tools/aaudio-sink keeps only module-aaudio-sink (the fallback). The release carries the relay and sink field fixes by MaxsTechReview (#338), credited there and in its AUTHORS. Device-proven on an AYANEO Pocket FIT: client sink 12 ms / 4 ms bursts, 0 underruns; FEZ on cachyos-11.0-20261005-slr on DirectAudio (took pulse before); FEZ on Proton Experimental unchanged; Curse of the Dead Gods on CachyOS from a cold prefix, DirectAudio on first launch. Co-authored-by: The412Banner <the412banner@users.noreply.github.com> |
||
|
|
82ad9330d0 | fix: revert gamescope patch 0113 now that games run on their own Xwayland (#372) | ||
|
|
1951d8bfde |
Fix Audio Crackling on Pulse & DirectAudio (#338)
* Build the DirectAudio relay from source
The relay helper shipped as a prebuilt libdirectaudiorelay.so with no source in the
repo. Its source (The412Banner/directaudio @ 3548a4a, the commit the bundled driver
names in version.txt) now lives in tools/directaudio-relay, unmodified, and CI and
build_local.sh compile it into jniLibs the way proot is built. It shares
da_relay_proto.h with the PulseAudio sink, which is byte-identical to its own copy.
* DirectAudio relay: prime before playing, one consumer, safe buffer floors
- The output stream started before the client had its ring, so every connection
opened with a run of short callbacks: six clicks per stream on a RedMagic, even idle.
The callback now plays silence until the ring holds its target, and only a real
underrun afterwards counts.
- An underrun ends the block with a short fade and waits for the ring to refill to
target before resuming with a fade in, instead of zero-padding every short callback.
Each callback spent starved grows the target, so one stall sizes it for the next.
With a producer freezing 60 ms every 2 s: 14 underruns before, 1 after.
- During a reopen the outgoing and incoming streams could both drain the ring. Only
the promoted stream reads it now; any other plays silence.
- The ring target starts at 40 ms instead of two bursts (8 ms) and keeps what it
learned across reopens.
- The device buffer is at least two bursts; 12 ms was a single burst on devices that
grant a 20 ms legacy stream.
* PulseAudio: the classic path plays through the native-rate AAudio sink
The classic path loaded the prebuilt 0.1.5 module, which opened AAudio at the daemon's
default 44.1 kHz: Android gave it a legacy stream (20 ms bursts) and resampled, after
PulseAudio had already resampled the 48 kHz clients down. Its data callback also waited
on the daemon's IO thread, and it started at two bursts and grew only after an audible
underrun. The app's own module-aaudio-sink, built by CI into the same bundle, now
carries that path:
- The stream opens at the device's rate (48 kHz) with the buffer at two bursts or
30 ms, whichever is more, still growing a burst per underrun.
- A write that times out part way keeps the rest for the next write instead of
dropping it.
- A stream reopened after a route change asks for the rate the first one got, so the
sink keeps its format instead of unloading.
* Audio: DirectAudio sink at audio priority, deeper client buffers, no decay probing
- module-directaudio-sink's IO thread asks for nice -16 like module-aaudio-sink's, so
the client's producer keeps up under game load.
- PULSE_LATENCY_MSEC=60 for the session: libpulse clients under FEX (the Steam
client, winepulse when DirectAudio is off) keep enough queued to ride out a late
wakeup.
- BANNER_AUDIO_DIRECT_DECAY=0: the driver's decay shrinks the device buffer every
10 s of quiet until it underruns again, a click by design.
Both sit ahead of Downloads/droiddeck-env and per-game environment, which still win.
* Audio: drop the session-wide PULSE_LATENCY_MSEC
On an AYN Thor it took the Steam client's stream to 110 ms (60 ms tlength on top of the
sink's 40 ms) with no underruns to show for it, and the delay was audible. Clients pick
their own buffers again; the per-game option still sets it.
* PulseAudio sinks: wait in the poll loop, never in a blocking call
Clients' audio reaches a sink as messages its IO thread handles in pa_rtpoll_run. The AAudio
sink spent each iteration inside a blocking AAudioStream_write for up to a burst, and the
DirectAudio sink inside a futex wait for up to a burst, so a client's data sat unread and its
stream ran dry: a Chromium-shaped client (44.1 kHz float, 30 ms tlength, 10 ms minreq) had
304 underflows in 30 s on the AAudio sink, heard as crackling in the Steam client. Bursts of
20 ms (a legacy stream, an AYN Thor) made it worst.
- module-aaudio-sink writes without blocking, renders only what the device has room for, and
comes back after half a burst. 0 underflows in 30 s, with and without 8 busy cores.
- module-directaudio-sink tops the ring up on the same half-burst timer instead of sleeping
on the relay's futex.
* DirectAudio relay: vendor the source the shipped binary was built from
The import took 3548a4a, the commit the bundled driver names in version.txt, but the relay
binary that shipped came from e4727e9 on the same branch (feat/linux-relay-mic): its strings
match a build of that source exactly. 3548a4a has no --mic-fifo, so with the microphone on the
relay printed its usage and exited, and DirectAudio played nothing. This is e4727e9 as
published; the fixes made on top of 3548a4a follow in the next commit.
* DirectAudio relay: prime before playing, one consumer, safe buffer floors (on e4727e9)
The same changes as
|
||
|
|
27782068a3 |
ESync, FSync, NTSync + OpenNow + FEX for Desktop Apps (#197)
* Make the Compatible Proton ARM64 the default and label compatible builds
The CompatToolMapping "0" default always points at DroidDeck's Proton
ARM64 tool, and per-game picks of adopted GE/CachyOS builds are kept,
including when the shortcuts writer remaps.
The tool is named after the Proton build it runs, Proton Experimental
ARM64 (Compatible), or Proton 11.0 ARM64 (Compatible) once that newer build
is installed. Adopted builds carry the same Compatible mark, read from a
string resource the app stages into the runtime, and the Proton page
explains which builds have the prefix fixes.
The registrar is renamed steam-compatibility and the tool
droiddeck-proton-arm64. Existing installs migrate on the next session: the
old tool directory is removed, every mapping that named it moves to the new
tool, and the retired bannerlator-steam-compat script is removed from the
runtime. CI and local packaging include the renamed script.
* Drop the duplicate R import left by merging main
* Add userspace ntsync for Proton on Android
Android kernels have no /dev/ntsync and its app policy refuses futex_waitv,
so every Proton 11 build here fell back to wineserver for every wait.
libblsession now serves /dev/ntsync itself: wineserver opens a memfd region,
each sync object is a timerfd that carries its slot, and the kernel ntsync
ioctls are answered in shared memory with futexes, following the kernel
driver's wake order. Valve's Proton Experimental ARM64, GE-Proton and
proton-cachyos use it unchanged.
Locks record their owner so a killed process cannot wedge the others,
signals are held off inside each critical section, dead processes and
exiting threads are swept, and object lifetimes follow close, dup2, dup3,
close_range and received descriptors.
Fast sync is on by default under Performance > Session fixes, and
PROTON_NO_NTSYNC=1 turns it off per game.
* Add droiddeck-esync as the default sync for Proton on Android
Without a kernel ntsync driver, Proton 11 builds here fell back to
wineserver for every wait. droiddeck-esync brings eventfd and shared-memory
sync to the exact Proton build a game runs on: a pack holds that build's
ntdll.so and wineserver with the patch series in tools/droiddeck-esync
applied, and the guest runs Proton from a shadow tree that links the stock
tool and swaps in those two files. A wineserver from a pack still prefers
/dev/ntsync when a kernel driver or droiddeck-ntsync is there.
Packs are built in Valve's SDK image from each release's own wine source
(Proton Experimental ARM64 tags, GE-Proton and proton-cachyos releases); the
control build must reproduce the release binaries byte for byte, and a
signed index lists the packs. The APK bundles the packs pinned in
release.env, the app fetches newer ones, and Steam's compatibility tool
picks the pack for each Proton build, so new Proton releases get packs
without an app update.
The ntdll side reads, writes and polls its eventfds with raw system calls,
so the guest's LD_PRELOAD wrappers stay out of the sync path. The server
abandons a mutex once a thread killed by TerminateThread has really exited
and when its process dies, and a mutex's owner and recursion count change
in one atomic step, so a killed owner cannot touch the next owner's count.
droiddeck-esync is on by default and PROTON_NO_ESYNC=1 turns it off per
game; droiddeck-ntsync, the userspace ntsync, is now an opt-in toggle.
* Watch Valve's Proton releases and build droiddeck-esync packs for them
A scheduled workflow reads the Proton ARM64 builds Steam ships (anonymous
steamcmd app info) and the upstream source tags, compares them with the
previous watch state and starts the pack build for any build that has no
pack yet. The pack build applies the patch series with --fuzz=0 and runs a
smoke test of each new pack against the esstress suite before it is
published.
* Add droiddeck-fsync, keep Steam and the app on one Proton, fix DirectAudio
droiddeck-fsync: libblsession answers futex_waitv(2), which the app
sandbox refuses, in userspace, so Proton's own fsync runs on the stock
Proton files with no pack. Waiters register the words they wait on in a
table beside the fsync shared memory and sleep on a futex of their own;
FUTEX_WAKE on the fsync memory wakes the registered waiters. Slots carry
one owner word that the sweeper and the owner claim with a CAS, and the
mapping table is rebuilt under a lock held across the real munmap, so a
reused address or a recycled slot cannot lose a waiter. It stands in for
a Proton build without a pack (droiddeck-ntsync where fsync is off), takes
over for games with esync off, and the "droiddeck-fsync first" toggle
(BL_FSYNC_FIRST, also per game) puts it ahead of the packs. The games
Proton keeps off fsync and esync never get it. A launch into a prefix
whose wineserver is still running keeps that server's sync choice.
One Proton for Steam and the app: the Components page's Proton is the
default Steam uses, applied live through the client while Steam runs
(droiddeck-steam-compat) and at the next start otherwise; a choice made in
Steam's menu comes back to the app. Requests are ordered by a sequence that
never goes backwards, and the page no longer jumps back to the default
after a swap or restore.
DirectAudio: the wrapper wrote the driver key with its backslashes
stripped, so no game ever used DirectAudio. Wine 11 also loads a builtin
only from the prefix, so the driver is now linked into system32 and
syswow64 before "directaudio,pulse" is selected; mmdevapi falls back to
winepulse whenever DirectAudio cannot start.
* Pick esync, ntsync or fsync from the Steam settings' Games group
A three-way tab row above the FEX preset sets the sync Proton games use. It
writes the existing switches together (droiddeck-ntsync, droiddeck-fsync
first, droiddeck-esync), so the Performance toggles and the tabs always agree,
starts on esync and keeps the choice until it is changed again.
* Make droiddeck-fsync the default sync for Proton games
A fresh install, or one that never picked a sync, starts on fsync; a choice made
in the Steam settings' Games group still sticks. Games Proton keeps off fsync
still fall back to droiddeck-esync.
* Add wineserver to the Wine sync tabs and order them ntsync, fsync, esync, wineserver
wineserver turns every in-process sync off so games wait through wineserver;
picking any other tab turns sync back on. The tabs shrink to fit a narrow pane.
* Shorten the Wine sync description
* Answer openat2 and execveat for FEX in the session preload
FEX opens every file of its x86 rootfs with openat2(RESOLVE_IN_ROOT) and
only falls back to the host path on EXDEV. Under proot on Android openat2
answers ENOSYS, so each lookup of an x86 library silently went to the host
and missed. The exported syscall() now turns openat2 into openat once the
real call reports ENOSYS: RESOLVE_IN_ROOT paths are taken relative to the
root fd (FEX has already resolved the links inside the rootfs), and an
absolute path under RESOLVE_BENEATH fails with EXDEV as the kernel would.
execveat with an absolute path, or relative to AT_FDCWD, and without
AT_EMPTY_PATH or AT_SYMLINK_NOFOLLOW, is plain execve; it is sent as such
because proot refuses execveat with a directory fd, which FEX uses when it
re-executes itself for a child x86 program.
* Run x86 Linux games and programs through FEX
Steam: Linux-only titles that have no ARM64 build (from the client's
appinfo cache: type game, demo, application or beta) are mapped to a new
compatibility tool, droiddeck-fex ("Linux x86 (FEX)", linux to linux,
no required runtime). Valve's own "fex" tool needs pressure-vessel, which
cannot run under proot, so a mapping to it or to a Steam Linux Runtime is
replaced; any other pick the user made stays. Titles that also ship for
Windows stay on Proton. When such a title is installed and FEX or the
sniper runtime is missing, the client is asked to install them.
droiddeck-fex runs the program under the FEX that Steam installs (app
3127680), with Steam Linux Runtime 3.0 (sniper, app 1628350) as the x86
rootfs:
- the sniper platform is linked in place from its usr-mtree (relative
links only, files/usr -> .), once per runtime version;
- the x86_64 and i386 builds of libblsession and libfakeinput go into the
runtime's lib/<triplet>/droiddeck and its etc/ld.so.preload, mirroring
the session's own list, so x86 programs get the pads and the session
fixes (FEX passes their system calls straight to the kernel, so the
ARM64 preloads cannot reach them);
- Config.json sets RootFS and the GL and Vulkan thunks, so x86 games draw
with the device's Turnip and Mesa;
- the FEX preset and the game's own environment from the Steam settings
apply, and ARM64 entries are dropped from LD_PRELOAD/LD_LIBRARY_PATH.
It also links ~/.steam/sdk64 and sdk32 to the client's x86 steamclient
when the client has one and nothing is there yet.
Desktop: x86_64 and i386 AppImages can be imported now; they unpack
through FEX (or unsquashfs) and record their architecture. Scripts,
AppImages and programs started in a run session use FEX automatically
when they are x86, and each added app has a "Use FEX" Auto/On/Off choice
in its edit dialog. The launchers' "still running" checks also look at
FEX processes, whose exe is FEX rather than the program. A GitHub release
without an ARM64 AppImage falls back to its x86_64 one. Decky's x86
loader starts through droiddeck-fex instead of the fex-mesa rootfs path,
which no runtime ships.
The x86 preloads are built against glibc 2.31 (Debian 11) so they load
in sniper: tools/linuxfs/build-x86-preloads.sh, run in CI and by
build_local.sh. fakeinput's stat hooks fall back to __xstat on a glibc
without a stat export, and mmap64 takes off64_t for the i386 build.
* Keep a FEX unixlib from outliving its DLL
A FEX package or original bundle without the aarch64-unix helpers left
the previous version's libarm64ecfex.so / libwow64fex.so in the Proton,
so the new DLLs loaded a unixlib built for another FEX. A swap now removes
the helpers the package does not carry; FEX then runs DLL-only, which it
already falls back to when Wine cannot load the unixlib.
* Fix the Wine sync choices an audit found
- wineserver tab: it passed Proton's environment through, so a build with
esync built in (GE, cachyos) still ran esync and a kernel ntsync would
still be used. It now sets PROTON_NO_ESYNC, PROTON_NO_FSYNC and
PROTON_NO_NTSYNC (unless the game's own environment sets them).
- ntsync tab: a Proton whose wineserver has no /dev/ntsync client got
wineserver-only sync although fsync would work. The hash cache records
whether the wineserver has one; without it the launch goes to
droiddeck-fsync, and no stand-in or pack turns droiddeck-ntsync on.
- A build with esync built in returned before the per-game fallbacks, so
a game that turns esync off ran with no in-process sync. It now gets
droiddeck-fsync, or droiddeck-ntsync where fsync is off too.
- When a pack's proton cannot start and the stock one is used, or the
selection fails, the prefix's record now says stock, so a second
launch into the same running prefix no longer picks the pack's ntdll.
- droiddeck-fsync: its mutex is held across fork and re-made in the
child, a closed or replaced shm fd is forgotten (close, dup2, dup3,
close_range, closefrom), and a waiter woken while it was leaving on a
timeout or signal reports the wake instead of losing it.
- BL_SYNC_MIN_NOFILE applies per game to every verb, debug logs carry
prefixes.json, the device report names the chosen sync instead of the
three raw switches, and PATCHES.md and the proot notes describe the
selector, the fsync default and droiddeck-fsync's futex_waitv.
* Name the runtime's scripts and files droiddeck, migrating old installs
The guest scripts are droiddeck-* now (droiddeck-session and the other 19),
as are the files the app and scripts generate (etc/droiddeck, the network
state files, the components dir, the Steam install stamp, the redist marker,
the extra-Proton wrapper and backups) and the compositor's own names
(libdroiddeckwayland, droiddeck_* sources, DROIDDECK_* switches, the
wl_output and seat names).
Installed runtimes carry on: LegacyNames moves etc/bannerlator and
share/bannerlator over and leaves relative links at the old paths before
every proot command, turns any old script into a link to its new name,
moves the generated files and points menu entries at the new scripts.
The session scripts and steam-compatibility move their markers on first
use, the components dir's desired.tsv is rewritten with it, and the
runtime counts as installed under either session script.
Kept: the banner_ahb_v1/banner_desktop_v1 wire names and BANNER_AUDIO_DIRECT
(read by prebuilt Turnip and Wine builds), Banners-Turnip and other
third-party names, BL_* switches, libblsession, and credits to Bannerlator.
* Unpack x86 AppImages without FEX, then ask Steam for FEX
Importing an x86 AppImage failed when FEX was not installed yet ("needs FEX
to unpack and no unsquashfs is installed"). AppImages now unpack with
uruntime (VHSgunzo, MIT, v0.8.1 aarch64, pinned by sha256 and shipped
unmodified with its licence), which reads SquashFS and DwarFS images of any
architecture natively. FEX's own --appimage-extract and unsquashfs stay as
fallbacks, and an ARM64 image whose own runtime cannot unpack it goes the
same way.
An x86 import with FEX missing records that FEX is wanted, so the next
Steam session requests FEX and the Steam Linux Runtime, and the program's
page says FEX is not set up yet and how to get it.
* Run Vulkan Qt Quick AppImages on Wayland
OpenNOW (Qt 6.8, Qt Quick on Vulkan) closed within two seconds in a run
mode. The session sends toolkits to gamescope's Xwayland, and Qt's xcb
backend only presents with Vulkan when Mesa's X11 WSI does, which needs
DRI3; Xwayland on KGSL has none, so Qt found no queue that can present and
aborted ("Failed to create RHI").
An AppImage that bundles Qt Quick, the Vulkan loader and Qt's Wayland
plugin now runs on gamescope's Wayland socket (the desktop's, outside
gamescope), where Turnip presents as it does for games, with Qt's xcb
backend as the fallback. SDL_VIDEODRIVER and XDG_SESSION_TYPE follow, so
helpers that pick their window system from them (OpenNOW's streamer) agree
with Qt. Everything else stays on X11; a qt file in the app's directory
(wayland or xcb) overrides the choice.
* Keep gamescope's WSI layer away from Qt apps on its Wayland socket
OpenNOW still closed at once: its FFmpeg (the Raspberry Pi fork, libavutil
61) creates its Vulkan queues internally synchronized whenever the driver
offers VK_KHR_internally_synchronized_queues, which DD-Turnip does. The
gamescope WSI layer registers every queue of a new device through
vkGetDeviceQueue, which only returns queues created without flags, so it
got VK_NULL_HANDLE and vkroots aborted on assert(obj) before Qt opened a
window.
Programs that draw on gamescope's Wayland socket do not need the layer,
which only carries X11 windows past Xwayland, so it is turned off for
them. OpenNOW bundles no Vulkan loader (it reaches Vulkan through Qt and
dlopen), so a binary that uses QVulkanInstance counts as a Vulkan app too,
and a Qt Quick app left on X11 says why in the session log.
* Keep the end of the session log, and say when FEX is missing
The session sends its output through head -c into session.log. head
writes through stdio, so it held up to 4 KB that proot's --kill-on-exit
threw away when the guest ended: every log stopped mid-line at a 4096-byte
boundary, losing exactly the lines that say why a program quit (an x86
AppImage's "x86 Linux programs need FEX" among them). dd writes each read
as it comes and keeps the same cap.
A run mode always ends with status 0 (gamescope does not pass its child's
on), so a program that could not start just closed. When the log says FEX
is missing, the ended screen now says so and how to get it.
The app reads FEX's readiness from status.json, which only a launch or an
import wrote, so it still said "not set up" after Steam installed FEX.
droiddeck-fex status rewrites it, and a Steam session ends with it while
FEX is wanted. FEX is also looked for at the tool's root and under files/,
and a tool folder without it lists what it holds.
* Let FEX and its runtime install runnable on an SD card library
A Steam library on shared storage loses the executable bits, so native
tools are staged in private directories bound over it; only Proton and
SteamLinuxRuntime folders were. FEX (3127680) installed there could never
run, droiddeck-fex saw no FEX and kept asking Steam for it. FEX and the
sniper runtime (1628350) now get private directories from their first
download, whatever their install folder is called.
* Keep fsync off in the pack smoke test
A runner whose kernel allows futex_waitv started stock Proton with fsync,
so the server-side baseline never said what the test waits for and every
pack was waved through as untestable; the esync run would have measured
fsync too.
* Judge a pack against stock's own esstress failures
Stock Proton fails esstress's dup wait all under server-side sync as well
(a Wine bug, seen on the phone too), and any stock failure made the test
call the runner unusable. A pack now fails only when it crashes, hangs or
fails a check stock passes.
* Ask Steam for FEX and its runtime one at a time
Both steam://install requests were started together, and the running client
took only the first: FEX installed, the sniper runtime FEX needs never did.
Each request now waits for the client to take it before the next.
* Bundle the first published droiddeck-esync packs in the apk
* Log how an x86 program under FEX ends
FEX keeps its own errors quiet unless asked, so a program it could not run
left nothing in the session log. Its log now goes to stderr, and the AppImage
launcher records the program's exit status or the signal that ended it.
* Show the log a failed AppImage program wrote
Programs like Eden stop themselves on a failed check and say why only in
their own log under the home folder. When the program ends badly, the end of
any log it wrote during the run is copied into the session log.
* Report where an x86 program under FEX hit an illegal instruction
A tiny x86_64 preload, built without libc, catches SIGILL and writes the
address, the instruction bytes and the mapping they belong to before the
program dies as it would have. droiddeck-fex preloads it into x86_64 programs.
* Load the fault reporter from the x86 runtime
Programs under FEX look libraries up in the x86 runtime, so the reporter is
copied there with the other preloads and named by its path inside it.
* Hand FEX its x86 runtime and thunks through the environment
Valve's FEX runs portable and reads its config beside itself, so the
Config.json droiddeck-fex writes was not seen: programs ran without the
runtime. The runtime, thunk libraries and thunk list now also go in FEX's
own environment variables, and each launch says what it was given.
* Use the sync pack built for the installed Proton release
Some Proton releases ship byte-identical ntdll.so and wineserver (Valve
11.0-2b/2c, CachyOS 0702/0703), so a pack built for a newer release
matched an older install exactly and the older install never fetched its
own pack. A pack from a newer release no longer counts as an exact match;
among matches the one built for the installed version wins, then rev.
The app ranks the pack a tool already uses the same way and only fetches
a pack that ranks higher, reads the release epoch from tools.tsv and
refetches when tools.tsv changes. A prefix whose server is still running
re-checks its recorded pack on waitforexitandrun and starts fresh when a
better one now applies.
* Keep published sync packs and revocations consistent
The publish step never replaces a pack that has an entry beside it; a
pack left without its entry by an interrupted run is replaced so the
build stops repeating. Discovery counts revocations the signed index does
not show yet, including superseded packs only the flavor releases list,
so the index is signed again. The release watch always builds every
flavor.
* Fetch the droiddeck-esync packs from DroidDeck-Components
The packs, the signed index and the apk bundle now live in the releases
of Droid-Deck/DroidDeck-Components, together with the pipeline that
builds them, so this repository keeps only the app and the guest code
that consumes them. The app's index and asset URLs point there,
release.env names the repository its bundle comes from, and the apk
builds drop bundled packs that the published index revokes.
* Stop the apk build when the published sync index cannot be read
* Ask Steam for one FEX dependency at a time
The client shows a confirmation dialog for each steam://install, and a
second request replaces the first dialog, so FEX was never installed
when the runtime was requested right after it. The next dependency is
now requested once the previous one has an app manifest.
* Use generic names in the AppImage test fixtures
* Give x86-64 apps under FEX the Vulkan thunk
Apps that bring their own glibc and Vulkan loader skipped FEX's thunk
overlay and loaded their bundled desktop Mesa drivers, which crash on the
phone's GPU during Vulkan setup. droiddeck-fex now adds an x86-64 audit
module when a program's bundled glibc and libstdc++ meet the thunk's
version needs. The module sends libvulkan.so.1 lookups to a nodelete stub
that needs FEX's thunk path. That keeps the thunk mapped when an app
unloads Vulkan and loads it again, since FEX keeps its first trampoline
links and the old addresses get reused.
The fault reporter now restores the default action before re-raising,
because FEX ignores SA_RESETHAND and the handler looped.
|
||
|
|
bc00bd9919 |
Fix runtime removal and first-run Steam setup (#185)
* Fix runtime removal races and show removal progress * Bootstrap Steam from the selected client channel * Show runtime progress below its Setup row * Always stage current session helpers and verify APK assets * Initialize Steam UI scale once using the handheld default |
||
|
|
37316f4677 | Add game launcher shortcuts | ||
|
|
e23cada4ea | Add Android clipboard text paste into Steam sessions | ||
|
|
42aff89ffd | Merge branch 'main' into feat/performance-fixes-2 | ||
|
|
a3fafcb10e | feat: feed the overlay's fan, GPU memory and Valve msm reader paths | ||
|
|
fc90b80fd8 |
Add proot fast path for in-process path lookups
Preload library answers stat/open/access/readlink in-process via a trampoline page proot 0014 lets through seccomp. On by default with a Performance toggle; also sets GLIBC_TUNABLES rseq=0 and malloc top_pad. |
||
|
|
7d1e1707be |
perf: faster local build, skip xalia and gamescope realtime by default, mic off by default, show the saved Deck mode (#85)
* perf: cache pinned downloads, skip unchanged proot rebuilds, and wait out a Docker Desktop restart in the local build * perf: skip xalia and gamescope realtime queues by default, add a realtime toggle, default the mic off * fix: show the saved Steam Deck mode on the Steam page before Performance has been opened |
||
|
|
080f72f7a0 |
build_local: sign with DroidDeck's key when a local .signing.env has it
A local build was signed with the testkey alone, which a release refuses
as an update ("signatures do not match"): testing on a device with a CI
build meant uninstalling it and losing its data first.
With an untracked .signing.env (RELEASE_KEYSTORE, RELEASE_STORE_PASSWORD,
RELEASE_KEY_ALIAS) in the checkout, or in the main checkout for a
worktree, build_local.sh finishes with tools/release/sign-apk.sh as CI's
main builds do, and the apk installs over a release. Without the file
nothing changes. DROIDDECK_SIGNING_ENV points at the file explicitly.
|
||
|
|
c7e692c5ec |
0.2.0 release notes with screenshots, plus launch transition and UI fixes (#46)
* docs(release): draft 0.2.0 beta notes * docs(release): credit prs and authors in 0.2.0 notes * docs(release): add #39 and #45 to 0.2.0 notes * chore: update readme * fix(ui): cover the whole screen with the capsule wall The wall was shifted right and then tilted around its own centre, which left the bottom-left of the home and loading screens bare. Centre it and size it to the tilted page's bounding box so every corner stays covered. * feat(ui): flood from the play button into the throbber Starting a session from a blue button no longer slides the session up over the front end. The button stretches out on staggered springs until the page is the ball's blue, the session opens on that same blue with no window animation, and the blue gathers into the throbber's ball before the throbber starts. Re-joining a running session, tiles and reduced motion keep the old rise. * docs(release): cover everything since 0.1 in the 0.2.0 notes 0.2.0 is the first release from the org, so list what DroidDeck does as a whole, grouped by area: org pull requests as #N, pull requests from before the move as The412Banner/DroidDeck#N, and the early work that predates pull requests by author. CI and build work gets one short section instead of a line each. * docs(release): add screenshots and animations to the 0.2.0 notes Lead with a game running and a few visual highlights, fold the full list into collapsible sections by area, and shorten every line to the feature and its credit. Pre-move pull requests read as legacy#N. * fix(session): give the desktop its own loading hints The loading screen's hints were written for Steam, so starting the desktop or an emulator said the first run downloads Steam and that leaving the app pauses Steam. Desktop and program sessions now rotate through hints about the desktop instead. * fix(build): skip incomplete NDKs when picking one locally An interrupted sdkmanager install leaves a directory like 28.2.13676358.failed under ndk/, which sorted last and was picked without a toolchain in it. Only consider directories that carry source.properties. * docs(release): show launching straight into Big Picture * docs(release): credit the launch transition to #46 |
||
|
|
fff1e837d3 |
Cemu (Wii U) from the front end and the desktop, and two session fixes
Cemu never showed a frame on DroidDeck: its Getting Started dialog blocked every first launch (the folder picker cannot reach ROMs), the session's controller helper aborted it, and the desktop's Vulkan renderer drew no cursor. With the Turnip KGSL fix in the driver and the haptic-optional Cemu in the catalog, this makes the app side complete: - bannerlator-pad-defaults seeds Cemu's settings.xml once: the Wii U games folder, Vulkan, and Cubeb audio on the default device for both the TV and the GamePad speaker at full volume (Wipeout 3 plays through the GamePad; Cemu's own default is 20 %). - The Cemu tile launches full screen (-f). - libfakeinput.so is preloaded into every session process and exported its static C++ runtime (~7000 symbols); programs unwound through it and aborted (shadPS4 in pthread_exit, Cemu's controller thread). Link with --exclude-libs,ALL, and fail the build if the runtime leaks out again. - On the Vulkan and GLES desktops the pointer worked but no cursor was drawn: wlroots hands the cursor to the app's compositor, which draws none. WLR_NO_HARDWARE_CURSORS=1 makes labwc composite it itself. Device-tested on the FIT: Super Mario 3D World in-game at 35-37 fps with sound, Deus Ex HR DC and Wipeout 3 launch with sound; RPCS3, Dolphin and a Steam session (FlatOut) unchanged on the same driver. |
||
|
|
5110cb6b47 | Add optional Steam startup | ||
|
|
93b9be67fc | Build local APK with CI payload parity (#20) | ||
|
|
531087be16 | Merge Droid-Deck main into fix/proot-performance | ||
|
|
3345f1c32b | Show build source and worktree state | ||
|
|
b8fcef622e |
proot: build the runtime's proot from source with WinNative's performance fixes
The runtime carries Termux's proot 5.1.107-70 as a prebuilt binary, built from termux/proot 4dba3afb (every file:line site in it matches that commit). The apk now builds that same commit with the NDK, with three patches ported from WinNative's feature/proot-enhancements, and prefers it over the runtime's copy: - Tracees are hashed by pid, so each ptrace stop finds its tracee without walking a list of every thread, and terminated tracees are swept only after a termination. - A clean absolute path three or more directories deep under the rootfs alone has its parent opened once and taken as canonical when the kernel's path for it is the one proot would build, instead of an lstat per component; the final component of a call that does not follow it is no longer lstat'ed. Extensions still see the parent's host path, and the f2fs workaround keeps the old walk. - A clone3 thread keeps its inherited flags when clone_args cannot be read. talloc is linked in statically from Samba's release tarball, so libproot.so needs only libc and libdl. On an x86_64 Android 15 emulator the same build ran a path and thread test suite with output identical to the unpatched commit (fake id, fake root, link2symlink, with and without seccomp), and a stat-heavy benchmark ran 25-27% faster, 31-36% with 1500 live threads. |
||
|
|
ae6dcc9798 |
Rename the app SteamDeck → DroidDeck
App name, app ID and code package: DroidDeck, com.droiddeck.launcher (sources moved to com/droiddeck/launcher, the 68 JNI functions renamed with them). The new app ID installs beside SteamDeck rather than over it. Everywhere the name was the app's own: the sidebar title, the session report, share zips, the shell title, wake-lock and log tags, User-Agents, the Compose theme, the Download folder and switch files (droiddeck-env, -osc, -driver, -tu-debug, -no-pad, -pad-log, -no-hud, -wlr-renderer; the old names are not read), and inside the runtime (droiddeck-desktop, Firefox's droiddeck.js, the shortcuts tag, the rumble socket, debug and cache paths). Build scripts, CI artifact (droiddeck-apk), CMake project, README and the progress log follow. Kept on purpose: Valve's Steam Deck (the -steamdeck flag, steamdeck_publicbeta/stable, 'Steam Deck mode', the steamos.cloud package URLs) and names inside the hosted desktop package (steamdeck.png, steamdeck-steam, steamdeck-bigpicture). 'Desktop installed' now tests for labwc instead of the launcher the app stages itself. A committed __pycache__ .pyc is removed. |
||
|
|
c03e62d583 | Add session suspend modes and audio recovery | ||
|
|
a1514ab5ad | Add reproducible local build and deploy helpers |