Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fj-app crashes when minimizing window #1424

Closed
kazatsuyu opened this issue Dec 6, 2022 · 10 comments · Fixed by #1447
Closed

fj-app crashes when minimizing window #1424

kazatsuyu opened this issue Dec 6, 2022 · 10 comments · Fixed by #1447
Labels
help wanted Extra attention is needed type: bug Something isn't working

Comments

@kazatsuyu
Copy link
Contributor

Version: fj-app 0.27.0 (development build; v0.27.0-39-g8c7dbc3b3)
OS: Windows 11 version 22H2 build 22621.819

It seems that this occurs when width: 0, height: 0 is notified in the resize event and the screen buffer surface is updated with that value during minimization.
For example, this kind of diff can avoid crashes.

diff --git a/crates/fj-window/src/event_loop_handler.rs b/crates/fj-window/src/event_loop_handler.rs
index 1e311d1d8..c0e0c62e7 100644
--- a/crates/fj-window/src/event_loop_handler.rs
+++ b/crates/fj-window/src/event_loop_handler.rs
@@ -131,10 +131,12 @@ impl EventLoopHandler {
                 event: WindowEvent::Resized(size),
                 ..
             } => {
-                self.new_size = Some(ScreenSize {
-                    width: size.width,
-                    height: size.height,
-                });
+                if size.width != 0 && size.height != 0 {
+                    self.new_size = Some(ScreenSize {
+                        width: size.width,
+                        height: size.height,
+                    });
+                }
             }
             Event::WindowEvent {
                 event: WindowEvent::MouseInput { state, button, .. },

However, even if the crash is avoided, there will be warnings:

WARN fj_viewer::viewer: Draw error: Error acquiring output surface: The underlying surface has changed, and therefore the swap chain must be updated
    at crates\fj-viewer\src\viewer.rs:146

So it might be better to have a mechanism to skip rendering during minimization.

@hannobraun hannobraun added type: bug Something isn't working help wanted Extra attention is needed topic: ui labels Dec 7, 2022
@hannobraun
Copy link
Owner

Thank you for opening this issue, @kazatsuyu! I can't reproduce this issue on Linux/Wayland, but it's not surprising to see these kinds of differences in behavior between platforms.

I can look into it at some point, but it would probably be more effective if someone who can test this directly would handle it. Adding https://github.com/hannobraun/Fornjot/labels/help%20wanted for that reason.

@zthompson47
Copy link
Contributor

I found an issue at gfx-rs/wgpu which appears to be the same. I'm also on Linux/Wayland so can't help with testing it.

It looks like using size.width.max(1) and size.height.max(1) is another way to avoid a panic, and I wonder if that would also make the Draw error warning go away.

@kazatsuyu
Copy link
Contributor Author

I tried using size.width.max(1) and size.height.max(1). It can avoid surface size error, but another error occurred.

First error:

thread 'main' panicked at 'Error in Surface::configure: Both `Surface` width and height must be non-zero. Wait to recreate the `Surface` until the window has non-zero area.', C:\Users\*****\.cargo\registry\src\github.aaakk.us.kg-1ecc6299db9ec823\wgpu-0.13.1\src\backend\direct.rs:281:9

New error:

thread 'main' panicked at 'wgpu error: Validation Error

Caused by:
    In a RenderPass
      note: encoder = `<CommandBuffer-(0, 27, Vulkan)>`
    In a set_scissor_rect command
    Scissor Rect { x: 1, y: 0, w: 1, h: 1 } is not contained in the render target Extent3d { width: 1, height: 1, depth_or_array_layers: 1 }

', C:\Users\*****\.cargo\registry\src\github.aaakk.us.kg-1ecc6299db9ec823\wgpu-0.13.1\src\backend\direct.rs:2391:5

Diff:

diff --git a/crates/fj-window/src/event_loop_handler.rs b/crates/fj-window/src/event_loop_handler.rs
index 1e311d1d8..f17ade831 100644
--- a/crates/fj-window/src/event_loop_handler.rs
+++ b/crates/fj-window/src/event_loop_handler.rs
@@ -132,8 +132,8 @@ impl EventLoopHandler {
                 ..
             } => {
                 self.new_size = Some(ScreenSize {
-                    width: size.width,
-                    height: size.height,
+                    width: size.width.max(1),
+                    height: size.height.max(1),
                 });
             }
             Event::WindowEvent {

@zthompson47
Copy link
Contributor

Thanks for testing that out, @kazatsuyu!

I was able to reproduce the new error on my system by hard-coding a minimal size:

self.new_size = Some(ScreenSize {
    width: 1,
    height: 1,
});

I played with the dimensions, and discovered that the crash happens as soon as the width is smaller than the width of the egui::SidePanel. On my system, a width < 362 will crash. A height > 0 seems to work fine in all cases.

So the reference to set_scissor_rect in the error makes sense if it's egui doing clipping.

I found a related issue at emilk/egui, and the fix to that issue is in the egui 0.20.0 release. Just not sure if it fixes this issue, and upgrading to 0.20.0 is non-trivial.

One weird thing is that if I manually resize the window, I can get the width below 362 just fine, and egui will collapse the gui to fit the smaller size. When I hard-code the dimensions in a WindowEvent::Resized event, I change the width in both:
https://github.com/hannobraun/Fornjot/blob/39fadcd9fe5effd839bf99f64d88efe672b975ea/crates/fj-window/src/event_loop_handler.rs#L93-L94
and:
https://github.com/hannobraun/Fornjot/blob/39fadcd9fe5effd839bf99f64d88efe672b975ea/crates/fj-window/src/event_loop_handler.rs#L134-L137
and it crashes. It seems like the dimensions are used in some other section of code, and my trick (and maybe a minimize in Windows) bypasses that code to produce the error. Just kinda guessing at this point, though.

@hannobraun
Copy link
Owner

hannobraun commented Dec 9, 2022

Yes, thank you for testing, @kazatsuyu, and thank you for looking into this @zthompson47!

I found a related issue at emilk/egui, and the fix to that issue is in the egui 0.20.0 release. Just not sure if it fixes this issue, and upgrading to 0.20.0 is non-trivial.

I like to track the latest dependency versions closely, and the new egui release also unblocks a bunch of other upgrades. Unless there is some truly difficult issue hindering the upgrade, I expect that to get done next week.

It seems like the dimensions are used in some other section of code, and my trick (and maybe a minimize in Windows) bypasses that code to produce the error. Just kinda guessing at this point, though.

That makes sense, but I don't know enough about egui internals to add more than speculation of my own. I'm guessing that the difference is in the events emitted on the different platforms. Minimizing on Linux/Wayland produces one sequence of events that ends up working, minimizing on Windows produces another sequence of events that causes problems with egui.

Maybe we should see what the egui upgrade next week brings. If that doesn't fix it, maybe we could compare the sequence of events produces on the different platforms (RUST_LOG=fj_window::run=trace cargo run).

@hannobraun
Copy link
Owner

I've just merged the upgrade to egui 0.20: #1444

I haven't checked whether that fixes the issue that @zthompson47 described.

@zthompson47
Copy link
Contributor

After the merge, hard-coding width: 1 and height: 1 now runs without a panic!

I suppose that means using max(1) might be a solution to @kazatsuyu's OP bug of crashing on minimize in Windows.

@kazatsuyu
Copy link
Contributor Author

Updating to bd2094b and using max(1) fixed the previous crashes, but there is still a problem with the warning below continuing to appear during minimization:

WARN fj_viewer::viewer: Draw error: Error acquiring output surface: The underlying surface has changed, and therefore the swap chain must be updated
    at crates\fj-viewer\src\viewer.rs:146

Additionally, when the window was repeatedly minimized and restored, the following error occurred and caused a crash.

thread 'main' panicked at 'wgpu error: Validation Error

Caused by:
    In Device::create_buffer
      note: label = `egui_vertex_buffer`
    Buffer size 353081600 is greater than the maximum buffer size (268435456)

', C:\Users\*****\.cargo\registry\src\github.aaakk.us.kg-1ecc6299db9ec823\wgpu-0.14.2\src\backend\direct.rs:2403:5

Although a large number of logs are generated during minimization, it is uncertain whether the warning is directly related to the crash. The newly occurring crash appears to be related to egui based on the log content. These issues may need to be addressed in separate issues.

@hannobraun
Copy link
Owner

Thank you for reporting back, @zthompson47 and @kazatsuyu!

I think, given the latest information from @kazatsuyu, it probably makes most sense to just stop rendering, if the size is zero. Something along the lines of if width > 0 && height > 0 { draw() } (simplified code; real code looks will look a bit different). I can look into that later, but if any of you want to, please feel free!

Additionally, when the window was repeatedly minimized and restored, the following error occurred and caused a crash.

It never ends, does it 😄

Let's address the other problem first, since we have a better handle on that. If this second problem still occurs once the other one is fixed, then we can open a separate issue for that.

kazatsuyu added a commit to kazatsuyu/Fornjot that referenced this issue Dec 13, 2022
@kazatsuyu
Copy link
Contributor Author

After stopping the rendering when the width or height of the window is 0, the crash and the warning disappeared, so I created a PR.

hannobraun pushed a commit to kazatsuyu/Fornjot that referenced this issue Dec 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed type: bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants