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 frame delta smoothing option (4.x) #52314

Merged
merged 1 commit into from
May 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
12 changes: 12 additions & 0 deletions core/core_bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,14 @@ int OS::get_low_processor_usage_mode_sleep_usec() const {
return ::OS::get_singleton()->get_low_processor_usage_mode_sleep_usec();
}

void OS::set_delta_smoothing(bool p_enabled) {
::OS::get_singleton()->set_delta_smoothing(p_enabled);
}

bool OS::is_delta_smoothing_enabled() const {
return ::OS::get_singleton()->is_delta_smoothing_enabled();
}

void OS::alert(const String &p_alert, const String &p_title) {
::OS::get_singleton()->alert(p_alert, p_title);
}
Expand Down Expand Up @@ -556,6 +564,9 @@ void OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_low_processor_usage_mode_sleep_usec", "usec"), &OS::set_low_processor_usage_mode_sleep_usec);
ClassDB::bind_method(D_METHOD("get_low_processor_usage_mode_sleep_usec"), &OS::get_low_processor_usage_mode_sleep_usec);

ClassDB::bind_method(D_METHOD("set_delta_smoothing", "delta_smoothing_enabled"), &OS::set_delta_smoothing);
ClassDB::bind_method(D_METHOD("is_delta_smoothing_enabled"), &OS::is_delta_smoothing_enabled);

ClassDB::bind_method(D_METHOD("get_processor_count"), &OS::get_processor_count);
ClassDB::bind_method(D_METHOD("get_processor_name"), &OS::get_processor_name);

Expand Down Expand Up @@ -631,6 +642,7 @@ void OS::_bind_methods() {

ADD_PROPERTY(PropertyInfo(Variant::BOOL, "low_processor_usage_mode"), "set_low_processor_usage_mode", "is_in_low_processor_usage_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "low_processor_usage_mode_sleep_usec"), "set_low_processor_usage_mode_sleep_usec", "get_low_processor_usage_mode_sleep_usec");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "delta_smoothing"), "set_delta_smoothing", "is_delta_smoothing_enabled");

// Those default values need to be specified for the docs generator,
// to avoid using values from the documentation writer's own OS instance.
Expand Down
3 changes: 3 additions & 0 deletions core/core_bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ class OS : public Object {
void set_low_processor_usage_mode_sleep_usec(int p_usec);
int get_low_processor_usage_mode_sleep_usec() const;

void set_delta_smoothing(bool p_enabled);
bool is_delta_smoothing_enabled() const;

void alert(const String &p_alert, const String &p_title = "ALERT!");
void crash(const String &p_message);

Expand Down
8 changes: 8 additions & 0 deletions core/os/os.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,14 @@ int OS::get_low_processor_usage_mode_sleep_usec() const {
return low_processor_usage_mode_sleep_usec;
}

void OS::set_delta_smoothing(bool p_enabled) {
_delta_smoothing_enabled = p_enabled;
}

bool OS::is_delta_smoothing_enabled() const {
return _delta_smoothing_enabled;
}

String OS::get_executable_path() const {
return _execpath;
}
Expand Down
4 changes: 4 additions & 0 deletions core/os/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class OS {
bool _keep_screen_on = true; // set default value to true, because this had been true before godot 2.0.
bool low_processor_usage_mode = false;
int low_processor_usage_mode_sleep_usec = 10000;
bool _delta_smoothing_enabled = false;
bool _verbose_stdout = false;
bool _debug_stdout = false;
String _local_clipboard;
Expand Down Expand Up @@ -154,6 +155,9 @@ class OS {
virtual void set_low_processor_usage_mode_sleep_usec(int p_usec);
virtual int get_low_processor_usage_mode_sleep_usec() const;

void set_delta_smoothing(bool p_enabled);
bool is_delta_smoothing_enabled() const;

virtual Vector<String> get_system_fonts() const { return Vector<String>(); };
virtual String get_system_font_path(const String &p_font_name, int p_weight = 400, int p_stretch = 100, bool p_italic = false) const { return String(); };
virtual Vector<String> get_system_font_path_for_text(const String &p_font_name, const String &p_text, const String &p_locale = String(), const String &p_script = String(), int p_weight = 400, int p_stretch = 100, bool p_italic = false) const { return Vector<String>(); };
Expand Down
3 changes: 3 additions & 0 deletions doc/classes/OS.xml
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,9 @@
</method>
</methods>
<members>
<member name="delta_smoothing" type="bool" setter="set_delta_smoothing" getter="is_delta_smoothing_enabled" default="true">
If [code]true[/code], the engine filters the time delta measured between each frame, and attempts to compensate for random variation. This will only operate on systems where V-Sync is active.
</member>
<member name="low_processor_usage_mode" type="bool" setter="set_low_processor_usage_mode" getter="is_in_low_processor_usage_mode" default="false">
If [code]true[/code], the engine optimizes for low processor usage by only refreshing the screen if needed. Can improve battery consumption on mobile.
</member>
Expand Down
5 changes: 5 additions & 0 deletions doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,11 @@
<member name="application/config/windows_native_icon" type="String" setter="" getter="" default="&quot;&quot;">
Icon set in [code].ico[/code] format used on Windows to set the game's icon. This is done automatically on start by calling [method DisplayServer.set_native_icon].
</member>
<member name="application/run/delta_smoothing" type="bool" setter="" getter="" default="true">
Time samples for frame deltas are subject to random variation introduced by the platform, even when frames are displayed at regular intervals thanks to V-Sync. This can lead to jitter. Delta smoothing can often give a better result by filtering the input deltas to correct for minor fluctuations from the refresh rate.
[b]Note:[/b] Delta smoothing is only attempted when [member display/window/vsync/vsync_mode] is set to [code]enabled[/code], as it does not work well without V-Sync.
It may take several seconds at a stable frame rate before the smoothing is initially activated. It will only be active on machines where performance is adequate to render frames at the refresh rate.
</member>
<member name="application/run/disable_stderr" type="bool" setter="" getter="" default="false">
If [code]true[/code], disables printing to standard error. If [code]true[/code], this also hides error and warning messages printed by [method @GlobalScope.push_error] and [method @GlobalScope.push_warning]. See also [member application/run/disable_stdout].
Changes to this setting will only be applied upon restarting the application.
Expand Down
30 changes: 30 additions & 0 deletions main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,7 @@ void Main::print_help(const char *p_binary) {
OS::get_singleton()->print(" --disable-render-loop Disable render loop so rendering only occurs when called explicitly from script.\n");
OS::get_singleton()->print(" --disable-crash-handler Disable crash handler when supported by the platform code.\n");
OS::get_singleton()->print(" --fixed-fps <fps> Force a fixed number of frames per second. This setting disables real-time synchronization.\n");
OS::get_singleton()->print(" --delta-smoothing <enable> Enable or disable frame delta smoothing ['enable', 'disable'].\n");
OS::get_singleton()->print(" --print-fps Print the frames per second to the stdout.\n");
OS::get_singleton()->print("\n");

Expand Down Expand Up @@ -791,6 +792,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
Vector<String> breakpoints;
bool use_custom_res = true;
bool force_res = false;
bool delta_smoothing_override = false;

String default_renderer = "";
String default_renderer_mobile = "";
Expand Down Expand Up @@ -1000,6 +1002,29 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
OS::get_singleton()->print("Missing tablet driver argument, aborting.\n");
goto error;
}
} else if (I->get() == "--delta-smoothing") {
if (I->next()) {
String string = I->next()->get();
bool recognised = false;
if (string == "enable") {
OS::get_singleton()->set_delta_smoothing(true);
delta_smoothing_override = true;
recognised = true;
}
if (string == "disable") {
OS::get_singleton()->set_delta_smoothing(false);
delta_smoothing_override = false;
recognised = true;
}
if (!recognised) {
OS::get_singleton()->print("Delta-smoothing argument not recognised, aborting.\n");
goto error;
}
N = I->next()->next();
} else {
OS::get_singleton()->print("Missing delta-smoothing argument, aborting.\n");
goto error;
}
} else if (I->get() == "--single-window") { // force single window

single_window = true;
Expand Down Expand Up @@ -1908,6 +1933,11 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(
GLOBAL_DEF(PropertyInfo(Variant::INT, "application/run/low_processor_mode_sleep_usec", PROPERTY_HINT_RANGE, "0,33200,1,or_greater"), 6900)); // Roughly 144 FPS

GLOBAL_DEF("application/run/delta_smoothing", true);
if (!delta_smoothing_override) {
OS::get_singleton()->set_delta_smoothing(GLOBAL_GET("application/run/delta_smoothing"));
}

GLOBAL_DEF("display/window/ios/allow_high_refresh_rate", true);
GLOBAL_DEF("display/window/ios/hide_home_indicator", true);
GLOBAL_DEF("display/window/ios/hide_status_bar", true);
Expand Down
Loading