fix(web): cap /play canvas at the real 2048 wgpu limit (corrects #97) #98

Merged
funman300 merged 1 commits from fix/web-canvas-cap-2048-constant into master 2026-06-24 01:14:49 +00:00
Owner

Corrects #97, which would not have fixed the crash.

The 1440p question

Nothing hardcodes 1440p. The 2560×1440 in the panic is the reporter's logical viewport: a 3840×2160 display at 150% scaling → devicePixelRatio 1.5 → 3840÷1.5 = 2560, 2160÷1.5 = 1440. With scale_factor_override(1.0) the surface is sized to that logical viewport.

Why #97 was wrong

#97 capped the canvas wrapper to gl.MAX_TEXTURE_SIZE — the hardware limit. On a 4K/integrated GPU that reports 8192+, so the wrapper was never capped and the 2560-wide surface still exceeded the limit → same panic.

The real ceiling is wgpu's, not the hardware's. On wasm, Bevy creates the device with Limits::downlevel_webgl2_defaults() (forced by WgpuSettingsPriority::WebGL2 in solitaire_web/src/lib.rs; confirmed in bevy_render-0.18.1/src/settings.rs:85), whose max_texture_dimension_2d is a fixed 2048 regardless of GPU. That's why the panic says "maximum extent … is 2048" even on a 4K-capable machine.

Fix

Cap the wrapper at the constant 2048. Reporter's surface 2560×1440 → 2048×1440 → within the limit. HTML-only, no wasm rebuild.

Trade-off / follow-ups

Any viewport over 2048 logical px now letterboxes (centered, black bars). On a 4K@150% that's 2048 of 2560 → ~256px bars each side. Two ways to improve, both needing a real-browser test:

  • Fill via upscale: keep the 2048 buffer but CSS-stretch the canvas to the full viewport (slightly soft, no bars).
  • Raise the wgpu limit: request a higher max_texture_dimension_2d in lib.rs (up to the adapter's real max) so capable GPUs render full-res — riskier (can fail device creation on true-2048 GPUs / interact with WebGL2 shader limits).

⚠️ Still can't browser-test here — needs Rhys to hard-reload /play after deploy and confirm it renders (letterboxed) instead of panicking.

🤖 Generated with Claude Code

**Corrects #97, which would not have fixed the crash.** ## The 1440p question Nothing hardcodes 1440p. The `2560×1440` in the panic is the reporter's **logical viewport**: a 3840×2160 display at 150% scaling → devicePixelRatio 1.5 → `3840÷1.5 = 2560`, `2160÷1.5 = 1440`. With `scale_factor_override(1.0)` the surface is sized to that logical viewport. ## Why #97 was wrong #97 capped the canvas wrapper to `gl.MAX_TEXTURE_SIZE` — the **hardware** limit. On a 4K/integrated GPU that reports 8192+, so the wrapper was never capped and the 2560-wide surface still exceeded the limit → same panic. The real ceiling is **wgpu's**, not the hardware's. On wasm, Bevy creates the device with `Limits::downlevel_webgl2_defaults()` (forced by `WgpuSettingsPriority::WebGL2` in `solitaire_web/src/lib.rs`; confirmed in `bevy_render-0.18.1/src/settings.rs:85`), whose `max_texture_dimension_2d` is a fixed **2048** regardless of GPU. That's why the panic says "maximum extent … is 2048" even on a 4K-capable machine. ## Fix Cap the wrapper at the constant **2048**. Reporter's surface 2560×1440 → 2048×1440 → within the limit. HTML-only, no wasm rebuild. ## Trade-off / follow-ups Any viewport over 2048 logical px now **letterboxes** (centered, black bars). On a 4K@150% that's 2048 of 2560 → ~256px bars each side. Two ways to improve, both needing a real-browser test: - **Fill via upscale:** keep the 2048 buffer but CSS-stretch the canvas to the full viewport (slightly soft, no bars). - **Raise the wgpu limit:** request a higher `max_texture_dimension_2d` in lib.rs (up to the adapter's real max) so capable GPUs render full-res — riskier (can fail device creation on true-2048 GPUs / interact with WebGL2 shader limits). ⚠️ Still can't browser-test here — needs Rhys to hard-reload `/play` after deploy and confirm it renders (letterboxed) instead of panicking. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
funman300 added 1 commit 2026-06-24 01:14:39 +00:00
Correction to the previous canvas clamp (#97), which would NOT have fixed the
crash. It capped the wrapper to the device's gl.MAX_TEXTURE_SIZE, but that's
the hardware limit — on a 4K/integrated GPU it reports 8192+, so the wrapper
was never actually capped and the 2560-wide surface still exceeded the limit.

The real ceiling is wgpu's, not the hardware's: on wasm Bevy creates the device
with Limits::downlevel_webgl2_defaults() (forced by WgpuSettingsPriority::WebGL2
in solitaire_web/src/lib.rs; see bevy_render-0.18.1 settings.rs), whose
max_texture_dimension_2d is a fixed 2048 regardless of GPU. So the cap must be
the constant 2048.

(For the record: the reporter's display is 3840x2160 at 150% scale → a 2560x1440
logical viewport, which is the 2560 in the panic — nothing hardcodes 1440p.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
funman300 merged commit 4850e9417e into master 2026-06-24 01:14:49 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: funman300/Ferrous-Solitaire#98