Detanup01 / gbe_fork

Fork of https://gitlab.com/Mr_Goldberg/goldberg_emulator
https://gitlab.com/Mr_Goldberg/goldberg_emulator
GNU Lesser General Public License v3.0
86 stars 36 forks source link

Dramatically decrease the startup locking/halt time when the overlay is enabled #27

Closed otavepto closed 3 weeks ago

otavepto commented 3 weeks ago

The way this works now is as follows:

Steam_User_Stats class

In the periodic callback of the Steam_User_Stats class, the achievements icons will be loaded from disk into memory via stb lib, this is done in batches each time the callback is run and the amount of images to load is controlled by paginated_achievements_icons.

Too much loading operations from disk will make the callback consume more time, and all steam callbacks will be impacted, but will happen once or twice at startup only. This can cause timeout in some games.

Too few loading operations from disk will make the callback consume way less time, and all steam callbacks will run just fine, but will keep recurring during startup until all icons are loaded. This can cause an overall slow down in the steam callback system.

With some testing it seemed 20 images is a moderate amount, it takes ~20-30 ms. This doesn't impact the original startup delay problem which happens when the overlay is enabled, but this is a much better way to load icons without impacting performance or causing timeout.

overlay class

This 2 biggest problems are

The second point caused 2 problems:

To fix the problem of icon uploading, the overlay proc now will attempt to upload 1 image at a time, since that takes ~30 ms on DirectX 12, the game FPS will be low at startup but will eventually rise again, and in case it keeps failing over and over forever, the user now has the option upload_achievements_icons_to_gpu.

To fix the 2 mutexes sync problem, the steam callback will try to lock the overlay mutex instead of forcefully doing it, if it failed to lock the mutex, it won't block the steam thread and instead bail out immediately, leaving the global mutex available. After all this callback is run periodically, so it should be fine to skip a few iterations. The other way around, which is making the overlay proc attempt to lock the global emu mutex and bailing out immediately if it failed, made the overlay skip a few frames as expected, but that obviously means it will be hidden in some frames and visible in others very rapidly, hence the flickering regression.

otavepto commented 3 weeks ago

One reasoning I forgot to mention, why uploading icons is done periodically? In games like payday 2 when you change resolutions all icons resources are invalidated, so they have to be re-uploaded again. If it was done once, changing resolutions would mean losing all icons until next game start.