docs/RUST.md: the emulator crash loop was the missing GLES fallback, with the panic-hook note
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
85869d02f8
commit
50e69995b6
1 file changed
+60
-5
+60
-5
@@ -716,11 +716,66 @@ closes it.
|
|||||||
devlog agent shrank the label type 18 -> 13 to make room (UI_RULES:
|
devlog agent shrank the label type 18 -> 13 to make room (UI_RULES:
|
||||||
never shrink text to fit). Put the controls in two rows or make the
|
never shrink text to fit). Put the controls in two rows or make the
|
||||||
header wrap; restore the size. Sonnet.
|
header wrap; restore the size. Sonnet.
|
||||||
- [ ] Bench app crash-loops on this checkout's emulator once
|
- [x] **Bench app crash-loops on this checkout's emulator (done
|
||||||
backgrounded (seen by the devlog agent, pre-existing; the phone's
|
2026-09-07).** Not the surface lifecycle at all, and not "once
|
||||||
resume works since ba2afba). Reproduce on the emulator's GLES path,
|
backgrounded" -- a build with the **default features** (no
|
||||||
read the crash from the devlog/`adb logcat`, fix. Opus if it is in
|
`force-gles`) never got a first frame. `AndroidRenderer::new`
|
||||||
the surface lifecycle.
|
(`iris/src/android/render.rs`) asked wgpu for `Backends::PRIMARY`,
|
||||||
|
which does not contain `GL`, and this emulator advertises a Vulkan ICD
|
||||||
|
with no adapter behind it: `RequestAdapterError::NotFound {
|
||||||
|
active_backends: VULKAN, no_adapter_backends: VULKAN,
|
||||||
|
supported_backends: VULKAN | GL }`, `.expect`ed, so SIGABRT, so the
|
||||||
|
launcher restarts it -- the loop. A `force-gles` build was never
|
||||||
|
affected, which is why the crash looked like it belonged to whatever
|
||||||
|
else was going on. **Root cause: iris refused a device whose only
|
||||||
|
usable adapter is a GLES one.**
|
||||||
|
|
||||||
|
**Fix, two halves.** (1) `AndroidRenderer::new` now probes for a
|
||||||
|
`PRIMARY` adapter with an instance that never touches the window and
|
||||||
|
rebuilds the instance on `Backends::GL` when there is none. The probe
|
||||||
|
is surface-free deliberately: **an Android window can be connected to
|
||||||
|
one graphics API only**, so a single instance carrying both backends
|
||||||
|
fails differently and worse -- Vulkan's
|
||||||
|
`vkCreateAndroidSurfaceKHR` claims the window in `create_surface` and
|
||||||
|
the GLES surface built from the same window then reports `In
|
||||||
|
Surface::configure / Invalid surface`, aborting one frame later in
|
||||||
|
`Surface::get_current_texture_view` ("Surface is not configured for
|
||||||
|
presentation"). That was measured here on the way to the fix, not
|
||||||
|
reasoned about. Vulkan still wins wherever it has an adapter, so
|
||||||
|
nothing changes on the phone. (2) The surface, adapter and device
|
||||||
|
requests all report through the `Result<Self, String>` this function
|
||||||
|
already returns, instead of two of the three panicking -- one rule for
|
||||||
|
the set, and `surface_changed` already puts that string on screen and
|
||||||
|
in the log ring.
|
||||||
|
|
||||||
|
**Evidence**, this checkout's emulator (API 36, x86_64, debug):
|
||||||
|
before, default features aborted on first launch with `Abort message:
|
||||||
|
'Could not get adapter!: NotFound {...}'`; after, `iris renderer: no
|
||||||
|
Backends(VULKAN | METAL | DX12 | BROWSER_WEBGPU) adapter on this
|
||||||
|
device, falling back to GLES` then `new renderer built (Gl)` and
|
||||||
|
frames. Then the cases the fix had no reason to touch, clean on both
|
||||||
|
the default build and a `force-gles` one: two background/return
|
||||||
|
cycles, rotate to landscape and back (`already_live=true`, the reuse
|
||||||
|
branch), a background/return after the rotation, and cold starts.
|
||||||
|
**Vulkan could not be exercised here** -- the probe's own answer is
|
||||||
|
that this emulator has no Vulkan adapter, which is the whole defect;
|
||||||
|
Vulkan remains only testable on Iris's phone.
|
||||||
|
|
||||||
|
**Also landed with it, and worth more than the fix**: a panic hook in
|
||||||
|
`iris/android-app/src/app_log.rs`. Checked first, rather than assumed:
|
||||||
|
under `panic = "abort"` a panic's message reaches the tombstone's
|
||||||
|
`Abort message` and **nothing else** -- not `log`, so not the ring, so
|
||||||
|
not Dev Updater's Runtime tab, which is the only surface Iris has on a
|
||||||
|
phone with no `adb`. The hook writes the message and its location at
|
||||||
|
`error` level, and -- because the ring is memory only and the process
|
||||||
|
is about to die -- also to `last-panic.txt` in the app's private
|
||||||
|
directory, which `set_crash_dir` (called from `nativeSetFilesDir`)
|
||||||
|
replays into the ring at `error` level on the next start and deletes.
|
||||||
|
So a crash loop now explains itself in the Runtime tab of the run
|
||||||
|
that is still up. Verified on the emulator by building the *unfixed*
|
||||||
|
renderer with the hook: `iris panic at .../render.rs:140:14: Could not
|
||||||
|
get adapter!: NotFound {...}` in the ring on the run that died, and
|
||||||
|
`iris app log: the previous run died -- ...` on the next one.
|
||||||
- [ ] Masks with a shape -- docs/LAYOUT.md "Masks with a shape (decided
|
- [ ] Masks with a shape -- docs/LAYOUT.md "Masks with a shape (decided
|
||||||
2026-09-07)". A mask references a primitive already drawn
|
2026-09-07)". A mask references a primitive already drawn
|
||||||
(rect SDF, texture or glyph alpha), chained and multiplied; `.masked()`
|
(rect SDF, texture or glyph alpha), chained and multiplied; `.masked()`
|
||||||
|
|||||||
Reference in new issue
Block a user