Move frame delaying functions from Main to OS.
Will allow specific platforms to override it and avoid blocking on the
main/GUI thread.
(cherry picked from commit 1b6e3458b2
)
This commit is contained in:
parent
3247ac4b0e
commit
dc8b7b3b17
4 changed files with 40 additions and 34 deletions
|
@ -41,6 +41,7 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
OS *OS::singleton = NULL;
|
OS *OS::singleton = NULL;
|
||||||
|
uint64_t OS::target_ticks = 0;
|
||||||
|
|
||||||
OS *OS::get_singleton() {
|
OS *OS::get_singleton() {
|
||||||
|
|
||||||
|
@ -767,6 +768,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() {
|
OS::OS() {
|
||||||
void *volatile stack_bottom;
|
void *volatile stack_bottom;
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ class Mutex;
|
||||||
class OS {
|
class OS {
|
||||||
|
|
||||||
static OS *singleton;
|
static OS *singleton;
|
||||||
|
static uint64_t target_ticks;
|
||||||
String _execpath;
|
String _execpath;
|
||||||
List<String> _cmdline;
|
List<String> _cmdline;
|
||||||
bool _keep_screen_on;
|
bool _keep_screen_on;
|
||||||
|
@ -345,6 +346,8 @@ public:
|
||||||
virtual uint64_t get_system_time_msecs() const;
|
virtual uint64_t get_system_time_msecs() const;
|
||||||
|
|
||||||
virtual void delay_usec(uint32_t p_usec) const = 0;
|
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;
|
virtual uint64_t get_ticks_usec() const = 0;
|
||||||
uint32_t get_ticks_msec() const;
|
uint32_t get_ticks_msec() const;
|
||||||
uint64_t get_splash_tick_msec() const;
|
uint64_t get_splash_tick_msec() const;
|
||||||
|
|
|
@ -2008,7 +2008,6 @@ bool Main::start() {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint64_t Main::last_ticks = 0;
|
uint64_t Main::last_ticks = 0;
|
||||||
uint64_t Main::target_ticks = 0;
|
|
||||||
uint32_t Main::frames = 0;
|
uint32_t Main::frames = 0;
|
||||||
uint32_t Main::frame = 0;
|
uint32_t Main::frame = 0;
|
||||||
bool Main::force_redraw_requested = false;
|
bool Main::force_redraw_requested = false;
|
||||||
|
@ -2163,38 +2162,7 @@ bool Main::iteration() {
|
||||||
if (fixed_fps != -1)
|
if (fixed_fps != -1)
|
||||||
return exit;
|
return exit;
|
||||||
|
|
||||||
const uint32_t frame_delay = Engine::get_singleton()->get_frame_delay();
|
OS::get_singleton()->add_frame_delay(OS::get_singleton()->can_draw());
|
||||||
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() || !OS::get_singleton()->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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
if (auto_build_solutions) {
|
if (auto_build_solutions) {
|
||||||
|
|
|
@ -39,7 +39,6 @@ class Main {
|
||||||
|
|
||||||
static void print_help(const char *p_binary);
|
static void print_help(const char *p_binary);
|
||||||
static uint64_t last_ticks;
|
static uint64_t last_ticks;
|
||||||
static uint64_t target_ticks;
|
|
||||||
static uint32_t frames;
|
static uint32_t frames;
|
||||||
static uint32_t frame;
|
static uint32_t frame;
|
||||||
static bool force_redraw_requested;
|
static bool force_redraw_requested;
|
||||||
|
|
Loading…
Reference in a new issue