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 --max-fps command-line argument to set a FPS limit #78012

Merged
merged 1 commit into from
Aug 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@
If [member display/window/vsync/vsync_mode] is [code]Enabled[/code], on monitors with variable refresh rate enabled (G-Sync/FreeSync), using a FPS limit a few frames lower than the monitor's refresh rate will [url=https://blurbusters.com/howto-low-lag-vsync-on/]reduce input lag while avoiding tearing[/url].
If [member display/window/vsync/vsync_mode] is [code]Disabled[/code], limiting the FPS to a high value that can be consistently reached on the system can reduce input lag compared to an uncapped framerate. Since this works by ensuring the GPU load is lower than 100%, this latency reduction is only effective in GPU-bottlenecked scenarios, not CPU-bottlenecked scenarios.
See also [member physics/common/physics_ticks_per_second].
This setting can be overridden using the [code]--max-fps <fps;>[/code] command line argument (including with a value of [code]0[/code] for unlimited framerate).
[b]Note:[/b] This property is only read when the project starts. To change the rendering FPS cap at runtime, set [member Engine.max_fps] instead.
</member>
<member name="audio/buses/channel_disable_threshold_db" type="float" setter="" getter="" default="-60.0">
Expand Down
18 changes: 17 additions & 1 deletion main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ static bool debug_paths = false;
static bool debug_navigation = false;
static bool debug_avoidance = false;
#endif
static int max_fps = -1;
static int frame_delay = 0;
static bool disable_render_loop = false;
static int fixed_fps = -1;
Expand Down Expand Up @@ -462,7 +463,8 @@ void Main::print_help(const char *p_binary) {
OS::get_singleton()->print(" --debug-avoidance Show navigation avoidance debug visuals when running the scene.\n");
OS::get_singleton()->print(" --debug-stringnames Print all StringName allocations to stdout when the engine quits.\n");
#endif
OS::get_singleton()->print(" --frame-delay <ms> Simulate high CPU load (delay each frame by <ms> milliseconds).\n");
OS::get_singleton()->print(" --max-fps <fps> Set a maximum number of frames per second rendered (can be used to limit power usage). A value of 0 results in unlimited framerate.\n");
OS::get_singleton()->print(" --frame-delay <ms> Simulate high CPU load (delay each frame by <ms> milliseconds). Do not use as a FPS limiter; use --max-fps instead.\n");
OS::get_singleton()->print(" --time-scale <scale> Force time scale (higher values are faster, 1.0 is normal speed).\n");
OS::get_singleton()->print(" --disable-vsync Forces disabling of vertical synchronization, even if enabled in the project settings. Does not override driver-level V-Sync enforcement.\n");
OS::get_singleton()->print(" --disable-render-loop Disable render loop so rendering only occurs when called explicitly from script.\n");
Expand Down Expand Up @@ -1329,6 +1331,16 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
goto error;
}

} else if (I->get() == "--max-fps") { // set maximum rendered FPS

if (I->next()) {
max_fps = I->next()->get().to_int();
N = I->next()->next();
} else {
OS::get_singleton()->print("Missing maximum FPS argument, aborting.\n");
goto error;
}

} else if (I->get() == "--frame-delay") { // force frame delay

if (I->next()) {
Expand Down Expand Up @@ -1961,6 +1973,10 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
OS::get_singleton()->set_environment("MVK_CONFIG_LOG_LEVEL", OS::get_singleton()->_verbose_stdout ? "3" : "1"); // 1 = Errors only, 3 = Info
#endif

if (max_fps >= 0) {
RandomShaper marked this conversation as resolved.
Show resolved Hide resolved
Engine::get_singleton()->set_max_fps(max_fps);
}

if (frame_delay == 0) {
frame_delay = GLOBAL_DEF(PropertyInfo(Variant::INT, "application/run/frame_delay_msec", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), 0);
}
Expand Down
5 changes: 4 additions & 1 deletion misc/dist/linux/godot.6
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,11 @@ Show collisions shapes when running the scene.
\fB\-\-debug\-navigation\fR
Show navigation polygons when running the scene.
.TP
\fB\-\-max\-fps\fR <fps>
Set a maximum number of frames per second rendered (can be used to limit power usage). A value of 0 results in unlimited framerate.
.TP
\fB\-\-frame\-delay\fR <ms>
Simulate high CPU load (delay each frame by <ms> milliseconds).
Simulate high CPU load (delay each frame by <ms> milliseconds). Do not use as a FPS limiter; use --max-fps instead.
.TP
\fB\-\-time\-scale\fR <scale>
Force time scale (higher values are faster, 1.0 is normal speed).
Expand Down
1 change: 1 addition & 0 deletions misc/dist/shell/_godot.zsh-completion
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ _arguments \
'--debug-collisions[show collision shapes when running the scene]' \
'--debug-navigation[show navigation polygons when running the scene]' \
'--debug-stringnames[print all StringName allocations to stdout when the engine quits]' \
'--frame-delay[set a maximum number of frames per second rendered (can be used to limit power usage), a value of 0 results in unlimited framerate]:maximum frames per seocnd' \
'--frame-delay[simulate high CPU load (delay each frame by the given number of milliseconds)]:number of milliseconds' \
'--time-scale[force time scale (higher values are faster, 1.0 is normal speed)]:time scale' \
'--disable-vsync[disable vertical synchronization even if enabled in the project settings]' \
Expand Down
1 change: 1 addition & 0 deletions misc/dist/shell/godot.bash-completion
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ _complete_godot_options() {
--debug-collisions
--debug-navigation
--debug-stringnames
--max-fps
--frame-delay
--time-scale
--disable-vsync
Expand Down
1 change: 1 addition & 0 deletions misc/dist/shell/godot.fish
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ complete -c godot -l remote-debug -d "Enable remote debugging"
complete -c godot -l debug-collisions -d "Show collision shapes when running the scene"
complete -c godot -l debug-navigation -d "Show navigation polygons when running the scene"
complete -c godot -l debug-stringnames -d "Print all StringName allocations to stdout when the engine quits"
complete -c godot -l max-fps -d "Set a maximum number of frames per second rendered (can be used to limit power usage), a value of 0 results in unlimited framerate" -x
complete -c godot -l frame-delay -d "Simulate high CPU load (delay each frame by the given number of milliseconds)" -x
complete -c godot -l time-scale -d "Force time scale (higher values are faster, 1.0 is normal speed)" -x
complete -c godot -l disable-render-loop -d "Disable render loop so rendering only occurs when called explicitly from script"
Expand Down