Internal fork based on upstream's qt6 branch (2d4db7e). Goal: OVRAS runs
natively on the Steam Frame (SteamOS, aarch64) with a minimal change set
against qt6 and only public Qt API.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5.4 KiB
5.4 KiB
Steam Frame port: requirements
Goal: OVRAS runs natively on the Steam Frame (SteamOS, aarch64) as a SteamVR dashboard tab.
- The work happens on the internal branch
steamframe, based on upstream'sqt6branch (commit2d4db7e). - Changes may later go back upstream as pull requests. That decision is made once something runs.
- Hence: the change set against
qt6stays minimal.
Background
- Proton: The Windows build runs on the Frame through Proton. Its laser y-axis is mirrored, which makes it unusable. Running x86 code under emulation plus Wine is also inefficient.
- State of
qt6: Upstream'sqt6branch (Qt 6.8, CMake) doesn't build on Linux yet. Its rendering uses QRhi, which is private Qt API (Qt_6_PRIVATE_API). - Template: The author's vrdashboard template (FrameAssistant commit
4a5b090) is verified on the Frame. It serves as a source of knowledge and of individual, self-contained parts: render backends, build container, packaging scripts. It does not replace OVRAS's platform layer.
Decisions
| Date | Decision |
|---|---|
| 2026-10-07 | Internal fork, Frame only. Windows and upstream pull requests are evaluated once something runs. |
| 2026-10-07 | Minimal change set against qt6, rather than rebuilding OVRAS on the template. |
| 2026-10-07 | Only public Qt API: rendering without QRhi, QML compiled to bytecode only. |
| 2026-10-07 | Manifest installation tries Utility first, then Background, on every platform. |
| 2026-10-07 | Vulkan is an additional render path, selected by a command-line option. OpenGL stays the default. |
| 2026-10-07 | Frame differences are switched by one build option. In the code they are capability constants, named by capability. |
| 2026-10-07 | OVRAS's code style everywhere, including template code that comes in. Only changed lines get formatted. |
| 2026-10-07 | Windows (render path, build) stays open until the upstream evaluation. |
| 2026-10-07 | Every code change gets comments that explain it fully, but directly and concisely. |
| 2026-10-07 | The app key stays steam.overlay.1009850; the Proton build gets uninstalled. |
Iteration 1: native start on the Frame
| # | Requirement | Acceptance criterion |
|---|---|---|
| R1 | Linux-only build: cross-build for aarch64 against the Frame's system Qt 6.8, plus an x86_64 build for development. Only public Qt API. | The container build succeeds. The package contains no Qt. objdump -T shows no Qt_6_PRIVATE_API symbols except QVulkan*. |
| R2 | Runs natively on the Frame as a dashboard tab, with install, auto-start and uninstall. | After deploy-to-frame.sh the tab appears and starts by itself after a reboot. Quitting doesn't crash. |
| R3 | Rendering: OpenGL by default, Vulkan as an additional path via a command-line option. Render only on change, capped at 60 fps. | Both paths show every page correctly. With Vulkan, container-test.sh reports no validation messages. |
| R4 | Input: laser the right way up, scrolling, text fields via OVRAS's existing SteamVR keyboard handling. OVRAS's SteamVR Input actions work. | Every page can be operated. An OVRAS action (e.g. push-to-talk) arrives. |
| R6 | Throttled tick: a fixed 11 ms timer (as in the template) instead of 1 ms polling. | Idle CPU load is measured and documented. There is no comparison with the Proton build. |
| R7 | OVRAS doesn't change the play area at start-up. Today MoveCenterTabController::zeroOffsets() commits the working copy as the live chaperone (CommitWorkingCopy(Live) in updateChaperoneResetData()) and creates a chaperone autosave profile. On the Frame this shifts the play area at start. |
After starting OVRAS on the Frame, the play area is where it was before. The log shows no CommitWorkingCopy. |
R5 (hiding features) was moved to iteration 2; the number stays reserved.
Not in iteration 1:
- hiding or disabling features
- checking features one by one
- replacements for the playspace features
- the template's D-pad navigation
- Windows
- upstream pull requests
Iteration 2 (planned)
| # | Requirement | Acceptance criterion |
|---|---|---|
| R5 | Hide features per the feature classification below. Features that don't work make no IVRChaperoneSetup zero-pose calls. |
The affected pages/groups are hidden; no chaperone-setup calls appear in the log. |
Then check features one by one and re-enable them.
Feature classification (basis for R5)
Native in SteamVR: according to SteamVR's release notes up to 2.17 / 2.18 beta and Valve's Steam Frame guide (researched 2026-10-07).
| Group | Features | Plan |
|---|---|---|
| Native in SteamVR | Wall height, fade distance, style, center marker, brightness, supersampling, motion smoothing, supersample filtering, audio devices and mirror, performance graph, do not disturb, pairing, tracker battery, recenter, native chaperone import; also Oculus SDK block and restart SteamVR (Windows only), multiple drivers | Hide |
| Only in OVRAS, useful on the Frame | Proximity warnings, dim when crouching, push-to-talk/-mute, mic mute when the HMD is taken off, audio and video profiles, color tint, media keys (MPRIS), alarm clock, statistics, per-game bindings | Keep; check one by one |
| Doesn't work, needs a replacement | Space drag/turn, gravity, height toggle, offsets, fix floor, chaperone profiles (geometry), all rotation features | Disable for now |
| Questionable | Keyboard input; cord untangling and rotation counter (the Frame is wireless) | Disable for now |