bevyengine / bevy

A refreshingly simple data-driven game engine built in Rust
https://bevyengine.org
Apache License 2.0
35.74k stars 3.54k forks source link

Mobile WASM not able to load bevy - Dimension X Value Exceeds Limit #7038

Open miketwenty1 opened 1 year ago

miketwenty1 commented 1 year ago

Mobile seems to be sort of broken. At least for brave/chrome on some androids.

Reopening since there is traction here to find a fix it seems & someone else also came across this: https://github.com/bevyengine/bevy/issues/7038#issuecomment-1773104845

I'm unsure if this is a "known" or an actual issue. I found this when trying to do some WASM stuff of my own, then realized the website examples also won't load for my mobile device. I'm unable to reproduce this with virtualized chrome devices on desktop (need to use my actual phone). Firefox seems to be working in some cases. Chrome seems to work in less cases.

UiButton is an example where it works with firefox but not chrome. I encourage you to try this on your phone and see if it works. (let me know). https://bevyengine.org/examples/ui/button/

(verison: 108.0.5359.128) chorme

nicopap commented 1 year ago

I can get the examples working on my GraphenOS (Android 13) Pixel 6a on Vanadium 108.0 (a Chromium fork of same version) The button shows up, but tapping it seems to result in inconsistent behavior.

Hmm, you seem to have Chromium version 108.1, maybe something that broke in the latest version? EDIT: well, seems like we have the same version of chromium

mockersf commented 1 year ago

Is it only something you see on UI examples? They are using some custom settings to only be active when there is user input, meaning you would need to be active in the canvas for them to load. I tried on an android device, it's harder and took longer on Chrome than in Firefox

nicopap commented 1 year ago

Ooh. So the button in the button example on Android only shows up after I tapped once on the screen (though the background has the default bevy bg, rather than dark-blue as on the screenshot).

Edit: In the ui/ui example, the sprites, text and red squares do not show up until I tap the screen.

miketwenty1 commented 1 year ago

Tried multiple devices and it works. This is very odd, I'm only able to reproduce this on Pixel 6 Pro with chromium browsers (brave/chrome). Even the Pixel 6 (non-pro) works!? with the ~same build version / version of chrome app. Note: firefox works fine for pixel 6 pro.

Since this isn't an overall android issue, and it may be something specific with Pixel 6 Pro chrome build, I'm going to close this.

MeoMix commented 12 months ago

Just noting that this is still an issue. My Pixel 6 Pro fails to load all Bevy WASM examples, but Firefox works fine. If there's any value in debug data here please let me know what to do. :)

miketwenty1 commented 12 months ago

@MeoMix When i was debugging it, it was because of a screen size error.. maybe because the pixel pro has a curved screen or something and it doesn't interpret it correctly.. I didn't understand at the time an easy solution to fix it. There's probably some javascript magic you can do to override the bad values.

MeoMix commented 12 months ago

@miketwenty1 Fascinating. Alright, thanks for the heads up.

image

Here's what I see after inspecting dev tools on my phone.

https://github.com/bevyengine/bevy/issues/4869 Related

https://groups.google.com/a/chromium.org/g/graphics-dev/c/E3V--C7OPpc Related?

DeviceDriver limits on my phone: Limits { max_texture_dimension_1d: 4096, max_texture_dimension_2d: 4096, max_texture_dimension_3d: 4096, max_texture_array_layers: 2048, max_bind_groups: 8, max_bindings_per_bind_group: 65535, max_dynamic_uniform_buffers_per_pipeline_layout: 16, max_dynamic_storage_buffers_per_pipeline_layout: 0, max_sampled_textures_per_shader_stage: 16, max_samplers_per_shader_stage: 16, max_storage_buffers_per_shader_stage: 0, max_storage_textures_per_shader_stage: 0, max_uniform_buffers_per_shader_stage: 16, max_uniform_buffer_binding_size: 65536, max_storage_buffer_binding_size: 0, max_vertex_buffers: 16, max_buffer_size: 2147483647, max_vertex_attributes: 16, max_vertex_buffer_array_stride: 4294967295, min_uniform_buffer_offset_alignment: 32, min_storage_buffer_offset_alignment: 256, max_inter_stage_shader_components: 124, max_compute_workgroup_storage_size: 0, max_compute_invocations_per_workgroup: 0, max_compute_workgroup_size_x: 0, max_compute_workgroup_size_y: 0, max_compute_workgroup_size_z: 0, max_compute_workgroups_per_dimension: 0, max_push_constant_size: 256 }

which shows some 4096, but doesn't explain why create_texture is being called in a way that results in exceeding it.

https://github.com/bevyengine/bevy/blob/7132404b38c993bfabd509113c4c49b7c2b18701/crates/bevy_render/src/view/mod.rs#L471 here's main_texture_a

So, if I go to https://www.mydevice.io/ on my phone it says my device pixel ratio is 3.5 and my JS screen width/height is 412/892.

So, my phone reports having a device pixel ratio of 3.5 and a width/height of 412/892. Applying DPR to these values and all seems fine, right? 412 3.5 = 1442 and 892 3.5 = 3122

However! If I look at WindowResolution I see:


impl Default for WindowResolution {
    fn default() -> Self {
        WindowResolution {
            physical_width: 1280,
            physical_height: 720,
            scale_factor_override: None,
            scale_factor: 1.0,
        }
    }
}

where its defaults are 1280 720. What is 1280 3.5? 4480! And that exceeds Limits.

So, I think that's what is happening but I dunno how to fix it just yet.

It's also the case that if I run window.innerWidth on my phone I get 1280 and if I run window.outerWidth on my phone that I get 412. It's possible there's code somewhere in here assuming outerWidth is always larger? IDK

miketwenty1 commented 12 months ago

@MeoMix if you don't mind.. if you do find find a fix, please update with findings.. I would really like to also implement it in my code base.

miketwenty1 commented 12 months ago

reopening to track with you.

MeoMix commented 12 months ago

I think we need to sit tight for a while.

https://github.com/rust-windowing/winit/pull/2849 https://github.com/rust-windowing/winit/issues/2524

winit has fixed the issue already but Bevy isn't using that version of winit. I don't think it's going to make it into Bevy 0.12. So my guess is that it'll work in 0.13, but that one could cherry-pick the change and patch their winit dependency locally if they were so inclined.

miketwenty1 commented 9 months ago

@MeoMix both of those are now closed/merged. What do you think the current blocker is for this?

MeoMix commented 9 months ago

There is none AFAIK. winit 0.29 was merged into bevy main a couple of weeks ago. I haven't pulled down bevy main to see if it fixed the issue for me yet though. If you're eager you can do that and report back otherwise will need to wait until bevy 0.13 ships

miketwenty1 commented 9 months ago

Yes this is still an issue while using main. The error is the same but reflects that it's using wgpu version 18 now.

.cargo/registry/src/index.crates.io-6f17d22bba15001f/wgpu-0.18.0/src/backend/direct.rs:3111:5:
wgpu error: Validation Error

Caused by:
    In Device::create_texture
      note: label = `main_texture_a`
    Dimension X value 4480 exceeds the limit of 4096

Is there a way I can override fix this?

MeoMix commented 9 months ago

Dang. I don't have any more information unfortunately. I was pretty sure that was the fix that needed to make it in, but, if it's not, it'll require triaging again and figuring out what else could be the issue.

miketwenty1 commented 9 months ago

Is there a way to just override it so it doesn't exceed limits?

MeoMix commented 9 months ago

If I knew I would tell you. I only have about an hour of experience with this issue back when I triaged it the first time. I have no idea without spending time digging into it.

miketwenty1 commented 9 months ago

I'm going to try a suggestion put here, i'll report back if this work around "works". https://github.com/bevyengine/bevy/issues/7591#issuecomment-1705759085

Edit: Tried, no dice.

daxpedda commented 9 months ago

@miketwenty1 which OS and browser are you using? Would it be possible to run the following JS code on that device:

const observer = new ResizeObserver((entries) => console.log(entries[0].devicePixelContentBoxSize[0]))
observer.observe(document.querySelector('canvas'))
miketwenty1 commented 9 months ago

After a loading the crashed game, I'm running the commands via USB Debugger:

Screenshot 2024-01-14 at 9 55 26 AM

ResizeObserverSize {inlineSize: 1442, blockSize: 2807}

daxpedda commented 9 months ago

Okay, that looks about right to me. This is the size Winit should be reporting. If Bevy is using a different size I assume it must not be coming from Winit.

@miketwenty1 which OS and browser are you using?

That would still be helpful.

miketwenty1 commented 9 months ago

these don't work.

chrome and chromium brave v1.61.116 chrome v120.0.6099.210 duckduckgo v5.183.0

all on the pixel 6 pro OS: android v14

note: firefox does work fwiw.

daxpedda commented 9 months ago

The resolution looks correct for this device. I guess at this point somebody just has to dig into the code and figure out where Bevy is getting these much bigger numbers from.

gnargfu commented 7 months ago

Stumbled onto this issue myself when trying to run it in WebGL on a mobile device. Dug around a bit in the code and noticed that

  1. None of the fullscreen modes takes seems to take resolution into consideration this made it run on a PC (which was our previous target) but not on a mobile device. (of course and with the exception of WindowMode::SizedFullscreen)
  2. fit_canvas_to_parent was set to true and that made the windowing take device ratio into consideration.

My simple fix was to set it to WindowMode::Windowed and fit_parent_to_canvas to false. Also added CSS rules for maximizing the canvas to fill the parent. (This was 0.12, in 0.13 just ignore everything I commented in regards to fit_parent_to_canvas).