summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo Locurcio <hugo.locurcio@hugo.pro>2020-06-15 19:30:39 +0200
committerHugo Locurcio <hugo.locurcio@hugo.pro>2020-06-15 19:30:39 +0200
commit1c28b269d8e691c9da2605c712120864ee1b467f (patch)
treebdb0d18167f3944dc32b7c863b7711d2527afff1
parent77990b87c2167c52e6271f6239bc4b9688977226 (diff)
Improve the low processor mode sleep precision
The Low Processor Usage Mode Sleep Usec setting is now used as a FPS limiter rather than a constant sleep duration. This will increase CPU/GPU usage slightly due to the higher effective FPS, but the increase in overall smoothness is worth it. If both Force Fps and Low Processor Usage Mode settings are enabled in the project settings, only the setting that causes the highest sleep duration will be retained. This closes #11030.
-rw-r--r--main/main.cpp36
1 files changed, 24 insertions, 12 deletions
diff --git a/main/main.cpp b/main/main.cpp
index 94dd895a26..610a6ed672 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -2258,25 +2258,37 @@ bool Main::iteration() {
return exit;
}
- if (OS::get_singleton()->is_in_low_processor_usage_mode() || !DisplayServer::get_singleton()->can_any_window_draw()) {
- OS::get_singleton()->delay_usec(OS::get_singleton()->get_low_processor_usage_mode_sleep_usec()); //apply some delay to force idle time
- } else {
- uint32_t frame_delay = Engine::get_singleton()->get_frame_delay();
- if (frame_delay) {
- OS::get_singleton()->delay_usec(Engine::get_singleton()->get_frame_delay() * 1000);
- }
+ const uint32_t frame_delay = Engine::get_singleton()->get_frame_delay();
+ if (frame_delay) {
+ // Add fixed frame delay to decrease CPU/GPU usage. This doesn't take
+ // the actual frame time into account.
+ // Due to the high fluctuation of the actual sleep duration, it's not recommended
+ // to use this as a FPS limiter.
+ OS::get_singleton()->delay_usec(frame_delay * 1000);
+ }
+
+ // Add a dynamic frame delay to decrease CPU/GPU usage. This takes the
+ // previous frame time into account for a smoother result.
+ uint64_t dynamic_delay = 0;
+ if (OS::get_singleton()->is_in_low_processor_usage_mode() || !DisplayServer::get_singleton()->window_can_draw()) {
+ dynamic_delay = OS::get_singleton()->get_low_processor_usage_mode_sleep_usec();
+ }
+ const int target_fps = Engine::get_singleton()->get_target_fps();
+ if (target_fps > 0 && !Engine::get_singleton()->is_editor_hint()) {
+ // Override the low processor usage mode sleep delay if the target FPS is lower.
+ dynamic_delay = MAX(dynamic_delay, (uint64_t)(1000000 / target_fps));
}
- int target_fps = Engine::get_singleton()->get_target_fps();
- if (target_fps > 0 && !Engine::get_singleton()->is_editor_hint()) {
- uint64_t time_step = 1000000L / target_fps;
- target_ticks += time_step;
+ if (dynamic_delay > 0) {
+ target_ticks += dynamic_delay;
uint64_t current_ticks = OS::get_singleton()->get_ticks_usec();
+
if (current_ticks < target_ticks) {
OS::get_singleton()->delay_usec(target_ticks - current_ticks);
}
+
current_ticks = OS::get_singleton()->get_ticks_usec();
- target_ticks = MIN(MAX(target_ticks, current_ticks - time_step), current_ticks + time_step);
+ target_ticks = MIN(MAX(target_ticks, current_ticks - dynamic_delay), current_ticks + dynamic_delay);
}
#ifdef TOOLS_ENABLED