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

Add a project setting to limit FPS on focus loss #76988

Closed

Conversation

Calinou
Copy link
Member

@Calinou Calinou commented May 12, 2023

Alternative implementation of #47812 (it turns out I forgot about that PR). See also #76987.

This is enabled by default to save power automatically and improve editor performance if the project is running in the background.

Testing project: test_max_fps_on_focus_loss.zip

@RandomShaper
Copy link
Member

Haven't checked deeply, but I think the editor already enters low processor mode on focus lost. Would we have after this PR two different code paths addressing the same issue?

@Calinou
Copy link
Member Author

Calinou commented May 12, 2023

Haven't checked deeply, but I think the editor already enters low processor mode on focus lost. Would we have after this PR two different code paths addressing the same issue?

The editor already has its own FPS limiting routine based on low-processor mode (which is always enabled unless you have Update Continuously enabled in the Editor Settings). This is why the code is guarded with if (!Engine::get_singleton()->is_editor_hint()).

We could merge these codepaths together in the long run by removing the editor's implementation and making it use the project code.

scene/main/window.cpp Outdated Show resolved Hide resolved
@akien-mga
Copy link
Member

I have some concerns about this:

  • This applies both when running the game in the editor, and when running the game once exported. Is it common behavior for games to throttle FPS when unfocused? I don't remember seeing that much, and I can see it be problematic for games which have logic that needs to stay synced with the ticks (timers, etc.).
  • During development, I think this would actually become a hindrance because I typically run the game windowed and alt-tab back and forth between the game and the editor. If the game throttles every time the editor gets focused, using the remote scene tree and the profiler becomes unreliable. The added prints for each focus change will also quickly get annoying.

This is enabled by default to save power automatically and improve
editor performance if the project is running in the background.
@Calinou Calinou force-pushed the add-fps-limit-on-focus-loss branch from 5a8e8e9 to 2a9e507 Compare May 12, 2023 16:54
if (max_fps_when_unfocused >= 1 || low_processor_mode_when_unfocused) {
if (OS::get_singleton()->is_stdout_verbose()) {
if (max_fps_when_unfocused >= 1 && low_processor_mode_when_unfocused) {
print_line(vformat("Window: Restoring previous maximum FPS (%d) and low-processor mode status (%s) on focus restore.", max_fps_on_focus_loss_previous, low_processor_mode_on_focus_loss_previous ? "enabled" : "disabled"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

print_verbose might be better?

Copy link
Member Author

@Calinou Calinou May 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's already encapsulated in is_stdout_verbose(); print_line() within is_stdout_verbose() is equivalent to print_verbose(). I did this to prevent conditions from being evaluated when --verbose is not used.

@lawnjelly
Copy link
Member

Possible problem with the logic here:

If you set a max_fps, low_processor_mode etc when not focused, and record the old one, what happens if the user changes these before you swap back? I don't know if these can be set at runtime, but if they can, it's possible to get out of sync.

Common solution for this problem is to maintain e.g. a focused and unfocused max_fps in the OS, and have a flag for whether focused, and just return the relevant one depending on the flag.

@Calinou
Copy link
Member Author

Calinou commented May 12, 2023

I don't remember seeing that much, and I can see it be problematic for games which have logic that needs to stay synced with the ticks (timers, etc.).

This can be an issue indeed. We could increase the maximum amount of physics ticks simulated per frame when the window is unfocused to avoid this issue. The default is 8; we could increase it to 48 when unfocused by default (assuming you'd be running at 60 FPS when focused).

As for timers, we should add a way to make them able to emit their signals multiple times in a single frame. This will need to be opt-in on a per-Timer basis to avoid performance issues, and also to preserve compatibility with existing projects.

I don't know if these can be set at runtime, but if they can, it's possible to get out of sync.

These can be set at run-time.

Common solution for this problem is to maintain e.g. a focused and unfocused max_fps in the OS, and have a flag for whether focused, and just return the relevant one depending on the flag.

Indeed, it would be better to have a property at the Engine level for this (like I did for #66367).

@Calinou
Copy link
Member Author

Calinou commented Jul 28, 2023

Closing in favor of #47812, which is a more robust implementation.

@Calinou Calinou closed this Jul 28, 2023
@YuriSizov YuriSizov removed this from the 4.x milestone Dec 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add a FPS limit for unfocused and minimized windows to decrease CPU/GPU usage
5 participants