fix(web): cap /play canvas at the real 2048 wgpu limit, not gl.MAX_TEXTURE_SIZE
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>
This commit is contained in:
@@ -23,26 +23,24 @@
|
|||||||
<body>
|
<body>
|
||||||
<div id="bevy-wrap"><canvas id="bevy-canvas"></canvas></div>
|
<div id="bevy-wrap"><canvas id="bevy-canvas"></canvas></div>
|
||||||
<script>
|
<script>
|
||||||
// Clamp the Bevy canvas's backing buffer to the device's real WebGL2
|
// Clamp the Bevy canvas's backing buffer to 2048px *before* the wasm
|
||||||
// MAX_TEXTURE_SIZE *before* the wasm initialises. `fit_canvas_to_parent`
|
// initialises. `fit_canvas_to_parent` sizes the wgpu surface to
|
||||||
// sizes the wgpu surface to #bevy-wrap; a surface larger than the GPU
|
// #bevy-wrap, and on wasm Bevy creates the device with
|
||||||
// limit (only 2048 on many laptop/integrated GPUs — e.g. a 2560-wide
|
// `Limits::downlevel_webgl2_defaults()` (forced by
|
||||||
// 1440p display) makes Surface::configure panic and kills the WASM
|
// `WgpuSettingsPriority::WebGL2` in solitaire_web/src/lib.rs), whose
|
||||||
// thread. Querying the real maximum means only devices at the 2048 floor
|
// `max_texture_dimension_2d` is a fixed **2048** — independent of the
|
||||||
// letterbox; everyone else still fills the viewport. Runs synchronously
|
// GPU's real MAX_TEXTURE_SIZE (which is why querying the hardware limit
|
||||||
// before the deferred module script below.
|
// doesn't help: a 4K/integrated GPU reports e.g. 8192 but wgpu still
|
||||||
(function clampCanvasToGpuLimit() {
|
// caps the surface at 2048). A surface wider/taller than 2048 makes
|
||||||
var max = 2048; // WebGL2 spec floor — the safe fallback
|
// Surface::configure panic and kill the WASM thread on the first frame
|
||||||
try {
|
// — e.g. a 3840x2160 display at 150% scale gives a 2560x1440 logical
|
||||||
var probe = document.createElement("canvas").getContext("webgl2");
|
// viewport → a 2560-wide surface. So the cap is the constant 2048.
|
||||||
if (probe) {
|
// Keep in sync with the wgpu limit selected in lib.rs.
|
||||||
var m = probe.getParameter(probe.MAX_TEXTURE_SIZE);
|
(function clampCanvasToWebgl2Limit() {
|
||||||
if (m && m > 0) max = m;
|
var MAX = 2048; // wgpu downlevel_webgl2_defaults().max_texture_dimension_2d
|
||||||
}
|
|
||||||
} catch (e) { /* keep the safe 2048 floor */ }
|
|
||||||
var wrap = document.getElementById("bevy-wrap");
|
var wrap = document.getElementById("bevy-wrap");
|
||||||
wrap.style.maxWidth = max + "px";
|
wrap.style.maxWidth = MAX + "px";
|
||||||
wrap.style.maxHeight = max + "px";
|
wrap.style.maxHeight = MAX + "px";
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
<script type="module">
|
<script type="module">
|
||||||
|
|||||||
Reference in New Issue
Block a user