- manifest.vrmanifest: binary_path_linux and binary_path_linux_arm. The Steam Frame's SteamVR reads only binary_path_linux_arm. - handleManifests(): connect as Utility app first (works without a running SteamVR, e.g. from the Windows installer); if SteamVR refuses Utility apps, as on the Steam Frame, connect as Background app. Fail right away on other errors instead of going through initializeOpenVR()'s retry loop. - main(): check --graphics-api before connecting to OpenVR, so a wrong value fails right away. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
125 lines
6.2 KiB
Markdown
125 lines
6.2 KiB
Markdown
# Steam Frame port: progress
|
||
|
||
## Iteration 1
|
||
|
||
### Step 1: build fixes, bytecode-only QML (2026-10-07)
|
||
|
||
**Changes:**
|
||
- **`CMakeLists.txt`:**
|
||
- `Core5Compat` removed (unused, not on the Frame).
|
||
- `GuiPrivate` requested explicitly. This is temporary, until step 3 replaces QRhi.
|
||
- `QT_QMLCACHEGEN_ARGUMENTS --only-bytecode`.
|
||
- OpenVR library directory per architecture (`linux64` / `linuxarm64` / `win64`), for
|
||
linking and for the copy next to the binary.
|
||
- `RPATH $ORIGIN`.
|
||
- `libXtst` linked.
|
||
- **`overlaycontroller.cpp`:** `d3d11.h` and `case QRhi::D3D11` only under `_WIN32`.
|
||
- **Logging:** 8 active easylogging `LOG(INFO)` calls became `qInfo()`
|
||
(`overlaycontroller.cpp` 6, `ChaperoneTabController.cpp` 1,
|
||
`MoveCenterTabController.cpp` 1). Commented-out `LOG` lines are left unchanged.
|
||
- Only changed lines are formatted (`git clang-format`).
|
||
|
||
**Results (x86_64, Arch, Qt 6.11.1, GCC):**
|
||
- The build succeeds, with 1463 compiler warnings, as in `qt6`.
|
||
- `objdump -T`: 7 `Qt_6_PRIVATE_API` symbols, all `QRhi…` (step 3). The
|
||
`QQmlPrivate::AOTCompiledContext` symbols are gone (bytecode-only QML).
|
||
- `libopenvr_api.so` is resolved from the binary's directory (`ldd`).
|
||
- Not started: without a running SteamVR the start hangs in OpenVR init (expected; tested
|
||
on the Frame in step 5).
|
||
|
||
### Step 2: platform option, R7, tick (2026-10-07)
|
||
|
||
**Changes:**
|
||
- **Platform option:**
|
||
- CMake option `OVRAS_STEAM_FRAME` (default OFF) sets the compile definition
|
||
`OVRAS_STEAM_FRAME=1`.
|
||
- New `src/utils/platform_capabilities.h` evaluates it as the only place. It holds
|
||
`k_chaperoneCommitSupported`, `k_defaultVsyncDisabled` and `k_defaultCustomTickRateMs`.
|
||
- **Tick (R6):**
|
||
- In "vsync disabled" mode, `m_pumpEventsTimer` runs directly at `customTickRateMs`
|
||
(`applyTickInterval()`, `Qt::PreciseTimer`); the 1 ms counting is gone.
|
||
- Changing the setting restarts the timer.
|
||
- Setting defaults in `settings_controller.h` come from the constants: Frame `true`/11 ms,
|
||
otherwise unchanged `false`/20 ms.
|
||
- **R7:** with `!k_chaperoneCommitSupported`:
|
||
- `updateChaperoneResetData()` and `applyChaperoneResetData()` skip
|
||
`CommitWorkingCopy`/`RevertWorkingCopy`. Each logs once per function.
|
||
- The init autosave profile is skipped.
|
||
|
||
**Results:**
|
||
- Both variants (default and `-DOVRAS_STEAM_FRAME=ON`) build on x86_64. The definition is
|
||
only set in the Frame variant (`compile_commands.json`).
|
||
- Not tested at runtime yet (Frame, step 5).
|
||
|
||
**Notes:**
|
||
- Another commit at start-up remains, but only on opt-in. `SetWidget()` applies a chaperone
|
||
profile and commits when "auto-apply chaperone" (`autoApplyChaperoneToggle`, default
|
||
`false`) is on. That's a chaperone-profile feature, so it belongs to R5 (iteration 2).
|
||
- clang-format reflows comment blocks next to new comments. Separate new comments from
|
||
existing commented-out code with a blank line, otherwise the diff grows.
|
||
|
||
### Step 3: rendering through public API, `--graphics-api`, mouse y, shutdown order (2026-10-07)
|
||
|
||
**Changes:**
|
||
- **`src/render/`** (new): `RenderBackend`, `OpenGLRenderBackend`, `VulkanRenderBackend` from
|
||
the template (`4a5b090`).
|
||
- Changes to the template code: `VRDASH_*` → `OVRAS_*` names, origin note in the file
|
||
header, references to `OverlayController`.
|
||
- Formatted completely in OVRAS style.
|
||
- One comment in `VulkanRenderBackend.h` was wrapped by hand, because the automatic
|
||
wrapping had broken its column layout.
|
||
- **`OverlayController`:**
|
||
- QRhi block replaced by `configureWindow` → `renderControl.initialize` →
|
||
`attachWindow` → `createRenderTarget`.
|
||
- `renderOverlay()` wraps the frame in `beginFrame`/`finishFrame`. It submits
|
||
`vrTextureBounds` + `vrTexture` while the context is current.
|
||
- `SetOverlayFromQRhiTexture`, the QRhi members and `QVulkanInstance` are removed.
|
||
- Render delay 5 → 16 ms (about 60 fps).
|
||
- **Shutdown:** `Shutdown()` runs only once. It calls `VR_Shutdown()`, then frees the
|
||
backend's render target (`releaseRenderTarget`, `detachWindow`).
|
||
- **Mouse y:** always flipped; the Linux un-flip and its TODO are removed.
|
||
- **`openvr_init::renderInterop()`:** Vulkan extensions and HMD GPU from SteamVR.
|
||
- **`main.cpp`:** parses `--graphics-api`, then `createRenderBackend` → `initialize` →
|
||
`QQuickWindow::setGraphicsApi` → `OverlayController`.
|
||
- **`setup.*`:** `--graphics-api opengl|vulkan` (default `opengl`). Unknown or not built in
|
||
→ error, exit code `GENERAL_FAILURE`.
|
||
- **CMake:**
|
||
- `GuiPrivate` is gone.
|
||
- The Vulkan backend is built when `QT_FEATURE_vulkan` is set (`OVRAS_HAS_VULKAN`).
|
||
|
||
**Results (x86_64, Qt 6.11.1):**
|
||
- The build succeeds. The Vulkan backend is built in.
|
||
- `objdump -T`: only `QVulkanDeviceFunctions::*` / `QVulkanFunctions::*` remain as
|
||
`Qt_6_PRIVATE_API`. Acceptance criterion R1 (symbols) is met.
|
||
- Warnings 1463 → 1630. The new code itself has none; the additional ones come from
|
||
`openvr.h` in the three new translation units.
|
||
- **Not tested yet:**
|
||
- running both backends, Vulkan validation, the snapshot test (step 5, with the
|
||
containers)
|
||
- mouse direction (Frame)
|
||
|
||
**Risk:**
|
||
- `MyTextField` opens the SteamVR keyboard on `activeFocus`. The template had to send the
|
||
offscreen window an explicit `FocusIn`, otherwise `activeFocusItem` stayed null. The `qt6`
|
||
branch doesn't send it. If text fields don't respond on the Frame, that is the cause (R4).
|
||
|
||
### Step 4: manifest and installation (2026-10-07)
|
||
|
||
**Changes:**
|
||
- **`manifest.vrmanifest`:** `binary_path_linux` and `binary_path_linux_arm` →
|
||
`AdvancedSettings_app`.
|
||
- **`manifest::handleManifests`:**
|
||
- `VR_Init(Utility)`; on `VRInitError_Init_NotAvailableToUtilityApps`,
|
||
`VR_Init(Background)`.
|
||
- Other errors: message and exit code `OPENVR_INIT_ERROR`, instead of
|
||
`initializeOpenVR`'s retry loop.
|
||
- **`main.cpp`:** `--graphics-api` is checked before connecting to OpenVR. A wrong value
|
||
used to fail only after `initializeOpenVR`'s retry loop.
|
||
|
||
**Results (x86_64, without SteamVR):**
|
||
- `--force-install-manifest` exits right away with `OPENVR_INIT_ERROR` (−2).
|
||
- `--graphics-api foo` exits right away with `GENERAL_FAILURE` (−1).
|
||
- The build tree contains the binary, `libopenvr_api.so`, both manifests,
|
||
`default_action_manifests/` and `res/`.
|
||
- Not tested yet: `Background` on the Frame (step 5).
|