summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/os/os.cpp36
-rw-r--r--core/os/os.h3
-rw-r--r--main/main.cpp34
-rw-r--r--main/main.h1
4 files changed, 40 insertions, 34 deletions
diff --git a/core/os/os.cpp b/core/os/os.cpp
index c842be333c..231069fcfb 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -41,6 +41,7 @@
#include <stdarg.h>
OS *OS::singleton = nullptr;
+uint64_t OS::target_ticks = 0;
OS *OS::get_singleton() {
return singleton;
@@ -468,6 +469,41 @@ void OS::close_midi_inputs() {
}
}
+void OS::add_frame_delay(bool p_can_draw) {
+ 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.
+ 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 (is_in_low_processor_usage_mode() || !p_can_draw) {
+ dynamic_delay = 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));
+ }
+
+ if (dynamic_delay > 0) {
+ target_ticks += dynamic_delay;
+ uint64_t current_ticks = get_ticks_usec();
+
+ if (current_ticks < target_ticks) {
+ delay_usec(target_ticks - current_ticks);
+ }
+
+ current_ticks = get_ticks_usec();
+ target_ticks = MIN(MAX(target_ticks, current_ticks - dynamic_delay), current_ticks + dynamic_delay);
+ }
+}
+
OS::OS() {
void *volatile stack_bottom;
diff --git a/core/os/os.h b/core/os/os.h
index 04e10518dc..f21c0d4df7 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -43,6 +43,7 @@
class OS {
static OS *singleton;
+ static uint64_t target_ticks;
String _execpath;
List<String> _cmdline;
bool _keep_screen_on = true; // set default value to true, because this had been true before godot 2.0.
@@ -212,6 +213,8 @@ public:
virtual double get_unix_time() const;
virtual void delay_usec(uint32_t p_usec) const = 0;
+ virtual void add_frame_delay(bool p_can_draw);
+
virtual uint64_t get_ticks_usec() const = 0;
uint32_t get_ticks_msec() const;
uint64_t get_splash_tick_msec() const;
diff --git a/main/main.cpp b/main/main.cpp
index 00760b39b0..0cccccdab3 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -2115,7 +2115,6 @@ bool Main::start() {
*/
uint64_t Main::last_ticks = 0;
-uint64_t Main::target_ticks = 0;
uint32_t Main::frames = 0;
uint32_t Main::frame = 0;
bool Main::force_redraw_requested = false;
@@ -2266,38 +2265,7 @@ bool Main::iteration() {
return exit;
}
- 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));
- }
-
- 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 - dynamic_delay), current_ticks + dynamic_delay);
- }
+ OS::get_singleton()->add_frame_delay(DisplayServer::get_singleton()->window_can_draw());
#ifdef TOOLS_ENABLED
if (auto_build_solutions) {
diff --git a/main/main.h b/main/main.h
index ab6917a65c..308128735c 100644
--- a/main/main.h
+++ b/main/main.h
@@ -38,7 +38,6 @@
class Main {
static void print_help(const char *p_binary);
static uint64_t last_ticks;
- static uint64_t target_ticks;
static uint32_t frames;
static uint32_t frame;
static bool force_redraw_requested;