diff --git a/solitaire_server/web/play.html b/solitaire_server/web/play.html index 50ea186..9c33444 100644 --- a/solitaire_server/web/play.html +++ b/solitaire_server/web/play.html @@ -7,23 +7,10 @@ diff --git a/solitaire_web/src/lib.rs b/solitaire_web/src/lib.rs index c64a2b5..2a99f7e 100644 --- a/solitaire_web/src/lib.rs +++ b/solitaire_web/src/lib.rs @@ -13,7 +13,7 @@ use bevy::asset::AssetMetaCheck; use bevy::prelude::*; use bevy::render::RenderPlugin; use bevy::render::settings::{RenderCreation, WgpuSettings, WgpuSettingsPriority}; -use bevy::window::{Window, WindowPlugin, WindowResizeConstraints, WindowResolution}; +use bevy::window::{Window, WindowPlugin, WindowResolution}; use solitaire_data::LocalOnlyProvider; use solitaire_engine::CoreGamePlugin; use wasm_bindgen::prelude::*; @@ -34,27 +34,15 @@ pub fn start() { fit_canvas_to_parent: true, // Prevent the browser stealing keyboard events and scroll. prevent_default_event_handling: true, - // Force scale_factor = 1.0 so the wgpu surface is sized in - // CSS/logical pixels rather than physical pixels. Without this, - // HiDPI displays (devicePixelRatio ≥ 2) produce a framebuffer - // whose physical width can exceed WebGL2's 2048-pixel per- - // dimension limit, causing a wgpu validation panic on the first - // resize event and killing the WASM thread. + // Render at CSS/logical pixels (scale_factor 1.0) rather + // than physical (CSS × devicePixelRatio). This keeps the + // surface smaller on HiDPI displays — lighter GPU load and + // stable sizing — at the cost of some crispness. The wgpu + // texture-dimension limit is now taken from the adapter (see + // the RenderPlugin below), so this is purely a quality/perf + // choice, no longer a crash-avoidance hack. resolution: WindowResolution::default() .with_scale_factor_override(1.0), - // Cap the surface at WebGL2's max texture dimension (2048). - // On wasm Bevy creates the device with - // `Limits::downlevel_webgl2_defaults()` (max_texture_dimension_2d - // = 2048), so a larger surface — e.g. a 4K display at 150% scale - // gives a 2560x1440 logical viewport — makes Surface::configure - // panic on the first frame. winit maps this constraint to the - // canvas's `max-width`/`max-height` style, so the surface can - // never exceed it. Viewports wider/taller than 2048 letterbox. - resize_constraints: WindowResizeConstraints { - max_width: 2048.0, - max_height: 2048.0, - ..default() - }, ..default() }), ..default() @@ -66,14 +54,19 @@ pub fn start() { meta_check: AssetMetaCheck::Never, ..default() }) - // WebGL2 priority constrains naga (the shader translator) to emit - // GLES 300es-compatible GLSL. Without this, Chromium's ANGLE driver - // rejects certain shader constructs (storage buffers, tight component - // limits) causing a fatal wgpu "Shader translation error". Firefox is - // more lenient; this setting makes both browsers work identically. + // `Functionality` makes wgpu adopt the *adapter's* real limits + // instead of the conservative `downlevel_webgl2_defaults()` that + // `WebGL2` priority forces. On the WebGL2 (Gl) backend the adapter + // already reports WebGL2-constrained features/limits — no storage + // buffers, etc., so shaders stay GLES-compatible on both Firefox and + // Chromium — but it reports the GPU's *true* `max_texture_dimension` + // (e.g. 16384) rather than 2048. The device is requested with exactly + // what the adapter offers, so creation can't fail, and the surface is + // no longer capped at 2048: large viewports (4K, etc.) render natively + // with no letterbox and no hardcoded cap. .set(RenderPlugin { render_creation: RenderCreation::Automatic(WgpuSettings { - priority: WgpuSettingsPriority::WebGL2, + priority: WgpuSettingsPriority::Functionality, ..default() }), ..default()