rust-windowing / winit

Window handling library in pure Rust
https://docs.rs/winit/
Apache License 2.0
4.8k stars 899 forks source link

WindowEvent::RedrawRequested: Lockup in Vulkan acquire_next_image(). #1143

Open cheako opened 5 years ago

cheako commented 5 years ago

Don't get mad at me for opening an issue, you don't have any other forum for reporting issues, mainly it's missing documentation that I need clarity on... or at least better documentation would always mean less requests for explaining things.

BTW: Fields of WaitCancelled aren't documented, like ppl are just going to guess that start is the time the event loop started.

What events are emitted AFTER ControlFlow::Exit is set? Do I need to make sure not to process any RedrawRequested? What documentation would suggest that I'm not looking at a case of winit doing something OTHER than just sending a CloseRequested event?

LoopDestroyed DOES clearly indicate it's the last event, but after looking around a bit I'm confused as to what events I should expect to see if I set ControlFlow::Exit in the CloseRequested event!

Background: I hit the X11 WM close button and the window froze. I set a 20hz timeout as a work around, but I don't yet know how to catch it. In my design(for resize events) I send an event prior to performing any actions, so the client has a chance to do things like(in the case of close requested) stop drawing/acquire images from the swap-chain... Can a redraw event be emitted after a close re

https://gitlab.com/cheako/hazel-rs/blob/cb0b459d107326febe1d97e2b6b224d9f44e2893/src/lib.rs#L302

The driver was inside something like xcb wait special event.

Edit: For got to say I saw this ONCE out of about 5 tries, I'll try and keep better track of the frequency. I had just fixed up resize to work as expected and the first time I got it working I couldn't exit. I tried several more times to reproduce the condition, but it's not easy.

Osspial commented 5 years ago

I think the current behavior is somewhat implementation-defined, actually. On Windows, we make a best-effort attempt to dispatch LoopDestroyed immediately after Exit is set, but will continue dispatching events if Win32 is stuck in a modal event loop and exit as soon as the OS lets us. I'm not sure what the exact behavior is elsewhere.

With all that said, the lack of specification here is an oversight that we should address. @vberger @francesca64 iirc you guys implemented the EL2 APIs for Linux and Mac. Got any thoughts on this?

elinorbgr commented 5 years ago

For the Wayland and X11 backend I interpreted ControlFlow::Exit as making the event loop finish its current batch of events, so until it sends an EventsCleared event, and then exit. This means that it indeed might send a last RedrawRequested before exiting.

Osspial commented 5 years ago

Technical response aside, I've got a few moderator-y points to mention:

Don't get mad at me for opening an issue, you don't have any other forum for reporting issues, mainly it's missing documentation that I need clarity on... or at least better documentation would always mean less requests for explaining things.

To be clear - we welcome issues describing problems with this library! The reason we had problems with your previous issues was the way you wrote them. Oftentimes they were unclear, encompassed multiple disparate problems, and/or hostile, which made it difficult and fairly stressful to deal with them. This issue is quite a bit better in those regards than many of the reports you've submitted in the past, and I really do appreciate the effort you've put into that.

That being said, I've got a couple minor points of feedback about this particular issue:

  1. This bit doesn't seem related to the overall problem you're describing. Could you spin it off into a different issue?

    BTW: Fields of WaitCancelled aren't documented, like ppl are just going to guess that start is the time the event loop started.

  2. I largely understand what you're saying in the background section, but a bit more information would be helpful there. Could you upload an event log from one of the times your program has frozen?

Again, other than those this is a significant step forwards. Thank you for improving your communication.

cheako commented 5 years ago

@vberger I can understand getting an RedrawRequested event prior to closing the event loop, that's not a problem. I'd love to trace what winit is doing, got any debug channels I could turn on?

I'll try and get an event trace and I understand that's important part of reporting this bug. Though I'd be more inclined to provide a trace if it included the xcb calls as well, as that's where I would guess the problem lies. Keeping in mind I'll have to make changes to my application to accomplish this, perhaps we should go about getting this information via another method. To be honest I havn't yet written to files in rust and currently my logging of events squelches the "interesting" ones in this case.

Here is a successful exit:

Sep 05 21:12:34.263 TRCE WindowEvent { window_id: WindowId(X(WindowId(50331649))), event: CloseRequested }
Sep 05 21:12:34.266 TRCE LoopDestroyed

Here is another successful exit, after I altered the squelching a bit:

Sep 05 21:20:39.945 TRCE WindowEvent { window_id: WindowId(X(WindowId(50331649))), event: CloseRequested }
Sep 05 21:20:39.945 TRCE on_update
Sep 05 21:20:39.946 TRCE EventsCleared
Sep 05 21:20:39.946 TRCE LoopDestroyed

This is from my library's client. The RedrawRequested event isn't emitted, but the "on_update" is from after the RenderPass is setup and therefore the image was acquired... Representing the client's part of the RedrawRequest.