Skip to content

Commit d603040

Browse files
committed
Merge pull request #78012 from Calinou/cli-add-max-fps-argument
Add a `--max-fps` command-line argument to set a FPS limit
2 parents e6e7925 + 4cab770 commit d603040

6 files changed

Lines changed: 25 additions & 2 deletions

File tree

doc/classes/ProjectSettings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@
348348
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].
349349
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.
350350
See also [member physics/common/physics_ticks_per_second].
351+
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).
351352
[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.
352353
</member>
353354
<member name="audio/buses/channel_disable_threshold_db" type="float" setter="" getter="" default="-60.0">

main/main.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ static bool debug_paths = false;
210210
static bool debug_navigation = false;
211211
static bool debug_avoidance = false;
212212
#endif
213+
static int max_fps = -1;
213214
static int frame_delay = 0;
214215
static bool disable_render_loop = false;
215216
static int fixed_fps = -1;
@@ -468,7 +469,8 @@ void Main::print_help(const char *p_binary) {
468469
OS::get_singleton()->print(" --debug-avoidance Show navigation avoidance debug visuals when running the scene.\n");
469470
OS::get_singleton()->print(" --debug-stringnames Print all StringName allocations to stdout when the engine quits.\n");
470471
#endif
471-
OS::get_singleton()->print(" --frame-delay <ms> Simulate high CPU load (delay each frame by <ms> milliseconds).\n");
472+
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");
473+
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");
472474
OS::get_singleton()->print(" --time-scale <scale> Force time scale (higher values are faster, 1.0 is normal speed).\n");
473475
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");
474476
OS::get_singleton()->print(" --disable-render-loop Disable render loop so rendering only occurs when called explicitly from script.\n");
@@ -1350,6 +1352,16 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
13501352
goto error;
13511353
}
13521354

1355+
} else if (I->get() == "--max-fps") { // set maximum rendered FPS
1356+
1357+
if (I->next()) {
1358+
max_fps = I->next()->get().to_int();
1359+
N = I->next()->next();
1360+
} else {
1361+
OS::get_singleton()->print("Missing maximum FPS argument, aborting.\n");
1362+
goto error;
1363+
}
1364+
13531365
} else if (I->get() == "--frame-delay") { // force frame delay
13541366

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

2002+
if (max_fps >= 0) {
2003+
Engine::get_singleton()->set_max_fps(max_fps);
2004+
}
2005+
19902006
if (frame_delay == 0) {
19912007
frame_delay = GLOBAL_DEF(PropertyInfo(Variant::INT, "application/run/frame_delay_msec", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), 0);
19922008
}

misc/dist/linux/godot.6

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,11 @@ Show collisions shapes when running the scene.
105105
\fB\-\-debug\-navigation\fR
106106
Show navigation polygons when running the scene.
107107
.TP
108+
\fB\-\-max\-fps\fR <fps>
109+
Set a maximum number of frames per second rendered (can be used to limit power usage). A value of 0 results in unlimited framerate.
110+
.TP
108111
\fB\-\-frame\-delay\fR <ms>
109-
Simulate high CPU load (delay each frame by <ms> milliseconds).
112+
Simulate high CPU load (delay each frame by <ms> milliseconds). Do not use as a FPS limiter; use --max-fps instead.
110113
.TP
111114
\fB\-\-time\-scale\fR <scale>
112115
Force time scale (higher values are faster, 1.0 is normal speed).

misc/dist/shell/_godot.zsh-completion

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ _arguments \
6969
'--debug-collisions[show collision shapes when running the scene]' \
7070
'--debug-navigation[show navigation polygons when running the scene]' \
7171
'--debug-stringnames[print all StringName allocations to stdout when the engine quits]' \
72+
'--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' \
7273
'--frame-delay[simulate high CPU load (delay each frame by the given number of milliseconds)]:number of milliseconds' \
7374
'--time-scale[force time scale (higher values are faster, 1.0 is normal speed)]:time scale' \
7475
'--disable-vsync[disable vertical synchronization even if enabled in the project settings]' \

misc/dist/shell/godot.bash-completion

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ _complete_godot_options() {
7272
--debug-collisions
7373
--debug-navigation
7474
--debug-stringnames
75+
--max-fps
7576
--frame-delay
7677
--time-scale
7778
--disable-vsync

misc/dist/shell/godot.fish

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ complete -c godot -l remote-debug -d "Enable remote debugging"
8989
complete -c godot -l debug-collisions -d "Show collision shapes when running the scene"
9090
complete -c godot -l debug-navigation -d "Show navigation polygons when running the scene"
9191
complete -c godot -l debug-stringnames -d "Print all StringName allocations to stdout when the engine quits"
92+
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
9293
complete -c godot -l frame-delay -d "Simulate high CPU load (delay each frame by the given number of milliseconds)" -x
9394
complete -c godot -l time-scale -d "Force time scale (higher values are faster, 1.0 is normal speed)" -x
9495
complete -c godot -l disable-render-loop -d "Disable render loop so rendering only occurs when called explicitly from script"

0 commit comments

Comments
 (0)