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 #48390

Merged
merged 1 commit into from
Jul 22, 2021
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/bind/core_bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,14 @@ bool _OS::is_vsync_via_compositor_enabled() const {
return OS::get_singleton()->is_vsync_via_compositor_enabled();
}

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();
}

_OS::PowerState _OS::get_power_state() {
return _OS::PowerState(OS::get_singleton()->get_power_state());
}
Expand Down Expand Up @@ -1369,6 +1377,9 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_vsync_via_compositor", "enable"), &_OS::set_vsync_via_compositor);
ClassDB::bind_method(D_METHOD("is_vsync_via_compositor_enabled"), &_OS::is_vsync_via_compositor_enabled);

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("has_feature", "tag_name"), &_OS::has_feature);

ClassDB::bind_method(D_METHOD("get_power_state"), &_OS::get_power_state);
Expand All @@ -1391,6 +1402,7 @@ void _OS::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "exit_code"), "set_exit_code", "get_exit_code");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "vsync_enabled"), "set_use_vsync", "is_vsync_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "vsync_via_compositor"), "set_vsync_via_compositor", "is_vsync_via_compositor_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "delta_smoothing"), "set_delta_smoothing", "is_delta_smoothing_enabled");
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, "keep_screen_on"), "set_keep_screen_on", "is_keep_screen_on");
Expand Down
3 changes: 3 additions & 0 deletions core/bind/core_bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,9 @@ class _OS : public Object {
void set_vsync_via_compositor(bool p_enable);
bool is_vsync_via_compositor_enabled() const;

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

PowerState get_power_state();
int get_power_seconds_left();
int get_power_percent_left();
Expand Down
9 changes: 9 additions & 0 deletions core/os/os.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,14 @@ bool OS::is_vsync_via_compositor_enabled() const {
return _vsync_via_compositor;
}

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

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

OS::PowerState OS::get_power_state() {
return POWERSTATE_UNKNOWN;
}
Expand Down Expand Up @@ -798,6 +806,7 @@ OS::OS() {
_no_window = false;
_exit_code = 0;
_orientation = SCREEN_LANDSCAPE;
_delta_smoothing_enabled = false;

_render_thread_mode = RENDER_THREAD_SAFE;

Expand Down
4 changes: 4 additions & 0 deletions core/os/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class OS {
bool _allow_layered;
bool _use_vsync;
bool _vsync_via_compositor;
bool _delta_smoothing_enabled;

char *last_error;

Expand Down Expand Up @@ -548,6 +549,9 @@ class OS {
void set_vsync_via_compositor(bool p_enable);
bool is_vsync_via_compositor_enabled() const;

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

virtual OS::PowerState get_power_state();
virtual int get_power_seconds_left();
virtual int get_power_percent_left();
Expand Down
3 changes: 3 additions & 0 deletions doc/classes/OS.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1104,6 +1104,9 @@
<member name="current_screen" type="int" setter="set_current_screen" getter="get_current_screen" default="0">
The current screen index (starting from 0).
</member>
<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="exit_code" type="int" setter="set_exit_code" getter="get_exit_code" default="0">
The exit code passed to the OS when the main loop exits. By convention, an exit code of [code]0[/code] indicates success whereas a non-zero exit code indicates an error. For portability reasons, the exit code should be set between 0 and 125 (inclusive).
[b]Note:[/b] This value will be ignored if using [method SceneTree.quit] with an [code]exit_code[/code] argument passed.
Expand Down
5 changes: 5 additions & 0 deletions doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,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 OS.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/use_vsync] is switched on, 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 @GDScript.push_error] and [method @GDScript.push_warning]. See also [member application/run/disable_stdout].
Changes to this setting will only be applied upon restarting the application.
Expand Down
14 changes: 14 additions & 0 deletions main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,8 @@ void Main::print_help(const char *p_binary) {
OS::get_singleton()->print(" --no-window Run with invisible window. Useful together with --script.\n");
OS::get_singleton()->print(" --enable-vsync-via-compositor When vsync is enabled, vsync via the OS' window compositor (Windows only).\n");
OS::get_singleton()->print(" --disable-vsync-via-compositor Disable vsync via the OS' window compositor (Windows only).\n");
OS::get_singleton()->print(" --enable-delta-smoothing When vsync is enabled, enabled frame delta smoothing.\n");
OS::get_singleton()->print(" --disable-delta-smoothing Disable frame delta smoothing.\n");
OS::get_singleton()->print(" --tablet-driver Tablet input driver (");
for (int i = 0; i < OS::get_singleton()->get_tablet_driver_count(); i++) {
if (i != 0) {
Expand Down Expand Up @@ -417,6 +419,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
bool use_custom_res = true;
bool force_res = false;
bool saw_vsync_via_compositor_override = false;
bool delta_smoothing_override = false;
#ifdef TOOLS_ENABLED
bool found_project = false;
#endif
Expand Down Expand Up @@ -637,6 +640,12 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
} else if (I->get() == "--disable-vsync-via-compositor") {
video_mode.vsync_via_compositor = false;
saw_vsync_via_compositor_override = true;
} else if (I->get() == "--enable-delta-smoothing") {
OS::get_singleton()->set_delta_smoothing(true);
delta_smoothing_override = true;
} else if (I->get() == "--disable-delta-smoothing") {
OS::get_singleton()->set_delta_smoothing(false);
delta_smoothing_override = true;
#endif
} else if (I->get() == "--profiling") { // enable profiling

Expand Down Expand Up @@ -1191,6 +1200,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("application/run/low_processor_mode_sleep_usec", 6900)); // Roughly 144 FPS
ProjectSettings::get_singleton()->set_custom_property_info("application/run/low_processor_mode_sleep_usec", PropertyInfo(Variant::INT, "application/run/low_processor_mode_sleep_usec", PROPERTY_HINT_RANGE, "0,33200,1,or_greater")); // No negative numbers

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/hide_home_indicator", true);
GLOBAL_DEF("input_devices/pointing/ios/touch_delay", 0.150);

Expand Down
Loading