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

Web: Emulation frequently hangs unless input events are sent continously #234

Closed
lukexor opened this issue May 17, 2024 · 16 comments · Fixed by #286
Closed

Web: Emulation frequently hangs unless input events are sent continously #234

lukexor opened this issue May 17, 2024 · 16 comments · Fixed by #286
Assignees
Labels
bug Something isn't working

Comments

@lukexor
Copy link
Owner

lukexor commented May 17, 2024

In an attempt to reduce CPU usage for desktop platforms, the event loop control flow is driven by WaitUntil and since the emulation is clocked on another thread, this poses no problems for emulation speed.

However this change to reduce CPU usage of the main thread has unintentionally tied the emulation rate on web (which is single threaded) to the rate at which events are received.

The easy fix should be to change web to always use Poll, which is more CPU intensive. It may be possible to always set it to WaitUntil with the target duration until next frame based on the audio queue (if audio is enabled) or the 60fps if disabled.

@lukexor lukexor added the bug Something isn't working label May 17, 2024
@lukexor lukexor self-assigned this May 17, 2024
@lukexor
Copy link
Owner Author

lukexor commented May 17, 2024

Original report was on Chrome Beta 126.0.6478.8 , Windows 11. I have yet to be able to reproduce this on the same browser on macOS. I made a change I hope will help resolve it, but I'll need to test on Windows 11, which I don't have right now. I'll run some tests on Windows 10 and leave this open for now.

@lukexor lukexor reopened this May 17, 2024
@lukexor lukexor mentioned this issue May 16, 2024
@sn-o-w
Copy link

sn-o-w commented May 18, 2024

Original report was on Chrome Beta 126.0.6478.8 , Windows 11. I have yet to be able to reproduce this on the same browser on macOS. I made a change I hope will help resolve it, but I'll need to test on Windows 11, which I don't have right now. I'll run some tests on Windows 10 and leave this open for now.

Hi!

I am the same person who emailed you. 😆

I can try again on my machine, but I'm running low on storage and can't compile TetaNES. 🤔

@lukexor
Copy link
Owner Author

lukexor commented May 18, 2024

Hi! Thanks, I'm hoping to get sometime this weekend on my windows 10 install. Unless Microsoft/chrome is somehow majorly changed how the priority scheduler queue works in windows 11 it shouldn't be all that different.

I also had a thought today that I probably just need a different timing mechanism anyways instead of relying on winits AboutToWait event. I think much of the winit development hasn't accounted for cases like emulation where you need a consistent timer not tied to the rate you receive events and where you don't want to churn the event loop as fast as possible by using Poll. The WaitUntil control flow seems like it would work for this but I haven't had much luck getting it to work.

I'm any event, I'm going to experiment some more. Having a reliable way to reproduce would help determine if it's actually solved or not though.

@lukexor
Copy link
Owner Author

lukexor commented May 19, 2024

@sn-o-w So I tested on Windows 10 with Chrome Beta 126.0.6478.8 with a known good ROM and couldn't reproduce any pauses due to lack of input. Have you tried other ROMs? There is a surprising range of quality when it comes to finding ROMs online. For example, do any of the included homebrew ROMs have a similar issue where it pauses intermittently unless the mouse is moved or keys pressed? I haven't deployed the changes I made yet, as I was trying to reproduce first to ensure they are useful changes that won't negatively impact overall performance. I assume you haven't made any other settings changes from the default Chrome or Window install that would throttle or otherwise limit performance?

@sn-o-w
Copy link

sn-o-w commented May 19, 2024

@sn-o-w So I tested on Windows 10 with Chrome Beta 126.0.6478.8 with a known good ROM and couldn't reproduce any pauses due to lack of input. Have you tried other ROMs? There is a surprising range of quality when it comes to finding ROMs online. For example, do any of the included homebrew ROMs have a similar issue where it pauses intermittently unless the mouse is moved or keys pressed? I haven't deployed the changes I made yet, as I was trying to reproduce first to ensure they are useful changes that won't negatively impact overall performance. I assume you haven't made any other settings changes from the default Chrome or Window install that would throttle or otherwise limit performance?

I only tried with Super Mario Bros, have no idea how other games work.

The NES file I tried is this: Super_Mario_Bros._World.zip [extract the archive]

And yes, I didn't make any other settings changes to the Chrome installation, everything else works optimally.


EDIT: Looks like this issue can be reproduced if "Performance Stats" is opened, despite those stats are currently broken.

Make sure to leave Performance Stats open! I can reproduce the issue with the homebrew ROMs I can easily select from the File menu.

@lukexor
Copy link
Owner Author

lukexor commented May 20, 2024

Thanks for those details. Unfortunately, I still can't reproduce. Performance stats being open should have little to do with it, because the reason it's not working is that toggling it via the Debug menu like that is simply failing to send the message to the emulation thread to start sending stats over a channel which is fixed on main already. If you toggle it via Ctrl-F the stats should work as expected.

It looks like you have a number of browser plugins installed - have you tried with a fresh install or incognito with extensions disabled? Another thing you may try is going directly to https://lukeworks.tech/tetanes-web/index.html - the primary page uses an iframe, which shouldn't normally be an issue, but best to rule it out.

From the video it's looking like the entire event loop is being halted - even the run time, that should be ticking every second is stalling out. The only way I can think that could happen is that if the underlying priority scheduler isn't calling back to winit frequently enough. With the Poll and WaitUntil control flow strategies for the web, winit relies on the Scheduler API: https://developer.mozilla.org/en-US/docs/Web/API/Scheduler/postTask

If disabling all plugins still results in issues, I'd need some more detailed performance profiling from Chrome to pin point why this is happening. You can do that by opening up the developer console and going to the Performance tab, recording, then reproducing the issue. You can then save the profile and attach it for further review.

@sn-o-w
Copy link

sn-o-w commented May 20, 2024

Thanks for those details. Unfortunately, I still can't reproduce. Performance stats being open should have little to do with it, because the reason it's not working is that toggling it via the Debug menu like that is simply failing to send the message to the emulation thread to start sending stats over a channel which is fixed on main already. If you toggle it via Ctrl-F the stats should work as expected.

It looks like you have a number of browser plugins installed - have you tried with a fresh install or incognito with extensions disabled? Another thing you may try is going directly to https://lukeworks.tech/tetanes-web/index.html - the primary page uses an iframe, which shouldn't normally be an issue, but best to rule it out.

From the video it's looking like the entire event loop is being halted - even the run time, that should be ticking every second is stalling out. The only way I can think that could happen is that if the underlying priority scheduler isn't calling back to winit frequently enough. With the Poll and WaitUntil control flow strategies for the web, winit relies on the Scheduler API: https://developer.mozilla.org/en-US/docs/Web/API/Scheduler/postTask

If disabling all plugins still results in issues, I'd need some more detailed performance profiling from Chrome to pin point why this is happening. You can do that by opening up the developer console and going to the Performance tab, recording, then reproducing the issue. You can then save the profile and attach it for further review.

I actually used https://lukeworks.tech/tetanes-web/index.html

I can reproduce the issue on Edge as well. I disabled all Edge extensions, but no use.

Here you go: https://we.tl/t-XAsl8ASTOa

The above profile is from Edge, with all Edge extensions disabled.

@lukexor
Copy link
Owner Author

lukexor commented May 20, 2024

I did have one other thought that may explain why having the performance stats window open affects things. GC pauses. Every string for the UI (label, button, etc) ends up being a new allocation each frame. It's an unfortunate limitation of the egui API right now and there's not a clear workaround - see emilk/egui#1098

The performance profiling I suggested earlier should also highlight if this is the case as you'll see large gaps in the animation frame due to GC pauses. It still doesn't quite explain why I can't reproduce on windows 10 with the same browser though so I still suspect some plugin interaction.

Does the issue happen if you have no other windows open and disable showing the menu bar as well?

@lukexor
Copy link
Owner Author

lukexor commented May 20, 2024

Oh great. That should help a lot. Thanks!

@lukexor lukexor changed the title Emulation clocking in web is unintentionally dependent on receiving events Web: Emulation frequently hangs unless input events are sent continously May 20, 2024
@sn-o-w
Copy link

sn-o-w commented May 20, 2024

Does the issue happen if you have no other windows open and disable showing the menu bar as well?

What do you mean by "disable showing the menu bar as well"? Do you mean the Performance Stats? Because if the Performance Stats window is not opened, everything is fine.

@lukexor
Copy link
Owner Author

lukexor commented May 20, 2024

Does the issue happen if you have no other windows open and disable showing the menu bar as well?

What do you mean by "disable showing the menu bar as well"? Do you mean the Performance Stats? Because if the Performance Stats window is not opened, everything is fine.

Under the Window menu there's a checkbox to hide the menu bar - Ctrl+E shortcut by default.

If things work fine, that's interesting. Can you try having the Preferences or Keybinds windows open (under the Config menu)? If those can stay open and not have this issue then that really narrows it down and I should be able to find a more permanent fix without needing to reproduce.

@sn-o-w
Copy link

sn-o-w commented May 20, 2024

Does the issue happen if you have no other windows open and disable showing the menu bar as well?

What do you mean by "disable showing the menu bar as well"? Do you mean the Performance Stats? Because if the Performance Stats window is not opened, everything is fine.

Under the Window menu there's a checkbox to hide the menu bar - Ctrl+E shortcut by default.

If things work fine, that's interesting. Can you try having the Preferences or Keybinds windows open (under the Config menu)? If those can stay open and not have this issue then that really narrows it down and I should be able to find a more permanent fix without needing to reproduce.

Whether the menu bar is hidden or not, the issue is reproducible as long as the Performance Stats window is opened.

I tried to open Preferences and Keybinds, but I cannot reproduce the issue with any of them opened.

@lukexor
Copy link
Owner Author

lukexor commented May 20, 2024

Great thank you for your help and patience figuring this out!

@lukexor lukexor mentioned this issue May 20, 2024
@lukexor
Copy link
Owner Author

lukexor commented May 21, 2024

I pushed some updates to the web version of you'd like to try them out. I'm still working out the CI/CD to automate releases

@sn-o-w
Copy link

sn-o-w commented May 21, 2024

I pushed some updates to the web version of you'd like to try them out. I'm still working out the CI/CD to automate releases

2024-05-21.16-08-35.mp4

It seems fixed to me. 👍 And the Performance Stats window is working.

@lukexor
Copy link
Owner Author

lukexor commented May 21, 2024

Great! Turns out it was a parking lot mutex lock on a repaint channel coming from inside egui, primarily used for the perf stats to ensure it's repainted at least once a second. Blocking is bad in wasm!

@lukexor lukexor closed this as completed May 21, 2024
This was referenced May 22, 2024
@lukexor lukexor mentioned this issue May 29, 2024
This was referenced May 30, 2024
@lukexor lukexor mentioned this issue Jun 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment