You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-04 12:00:25 +00:00
Use system timer/wait functions for frame delay when screen reader is active.
This commit is contained in:
@@ -658,7 +658,25 @@ void OS::close_midi_inputs() {
|
||||
}
|
||||
}
|
||||
|
||||
void OS::add_frame_delay(bool p_can_draw) {
|
||||
uint64_t OS::get_frame_delay(bool p_can_draw) const {
|
||||
const uint32_t frame_delay = Engine::get_singleton()->get_frame_delay();
|
||||
|
||||
// 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 max_fps = Engine::get_singleton()->get_max_fps();
|
||||
if (max_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 / max_fps));
|
||||
}
|
||||
|
||||
return frame_delay + dynamic_delay;
|
||||
}
|
||||
|
||||
void OS::add_frame_delay(bool p_can_draw, bool p_wake_for_events) {
|
||||
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
|
||||
|
||||
@@ -247,7 +247,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 void add_frame_delay(bool p_can_draw, bool p_wake_for_events);
|
||||
virtual uint64_t get_frame_delay(bool p_can_draw) const;
|
||||
|
||||
virtual uint64_t get_ticks_usec() const = 0;
|
||||
uint64_t get_ticks_msec() const;
|
||||
|
||||
@@ -4855,11 +4855,9 @@ bool Main::iteration() {
|
||||
}
|
||||
|
||||
SceneTree *scene_tree = SceneTree::get_singleton();
|
||||
bool skip_delay = scene_tree && scene_tree->is_accessibility_enabled();
|
||||
bool wake_for_events = scene_tree && scene_tree->is_accessibility_enabled();
|
||||
|
||||
if (!skip_delay) {
|
||||
OS::get_singleton()->add_frame_delay(DisplayServer::get_singleton()->window_can_draw());
|
||||
}
|
||||
OS::get_singleton()->add_frame_delay(DisplayServer::get_singleton()->window_can_draw(), wake_for_events);
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
if (auto_build_solutions) {
|
||||
|
||||
@@ -64,6 +64,7 @@ protected:
|
||||
|
||||
JoypadApple *joypad_apple = nullptr;
|
||||
MainLoop *main_loop = nullptr;
|
||||
CFRunLoopTimerRef wait_timer = nil;
|
||||
|
||||
virtual void initialize_core() override;
|
||||
virtual void initialize() override;
|
||||
@@ -75,6 +76,8 @@ protected:
|
||||
virtual void delete_main_loop() override;
|
||||
|
||||
public:
|
||||
virtual void add_frame_delay(bool p_can_draw, bool p_wake_for_events) override;
|
||||
|
||||
virtual void set_cmdline_platform_args(const List<String> &p_args);
|
||||
virtual List<String> get_cmdline_platform_args() const override;
|
||||
|
||||
|
||||
@@ -49,6 +49,28 @@
|
||||
#include <os/log.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
void OS_MacOS::add_frame_delay(bool p_can_draw, bool p_wake_for_events) {
|
||||
if (p_wake_for_events) {
|
||||
uint64_t delay = get_frame_delay(p_can_draw);
|
||||
if (delay == 0) {
|
||||
return;
|
||||
}
|
||||
if (wait_timer) {
|
||||
CFRunLoopTimerInvalidate(wait_timer);
|
||||
CFRelease(wait_timer);
|
||||
}
|
||||
wait_timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + (double(delay) / 1000000.0), 0, 0, 0,
|
||||
^(CFRunLoopTimerRef timer) {
|
||||
CFRunLoopTimerInvalidate(wait_timer);
|
||||
CFRelease(wait_timer);
|
||||
wait_timer = nil;
|
||||
});
|
||||
CFRunLoopAddTimer(CFRunLoopGetCurrent(), wait_timer, kCFRunLoopCommonModes);
|
||||
return;
|
||||
}
|
||||
OS_Unix::add_frame_delay(p_can_draw, p_wake_for_events);
|
||||
}
|
||||
|
||||
void OS_MacOS::initialize() {
|
||||
crash_handler.initialize();
|
||||
|
||||
@@ -995,8 +1017,9 @@ void OS_MacOS_NSApp::start_main() {
|
||||
ERR_PRINT("NSException: " + String::utf8([exception reason].UTF8String));
|
||||
}
|
||||
}
|
||||
|
||||
CFRunLoopWakeUp(CFRunLoopGetCurrent()); // Prevent main loop from sleeping.
|
||||
if (wait_timer == nil) {
|
||||
CFRunLoopWakeUp(CFRunLoopGetCurrent()); // Prevent main loop from sleeping.
|
||||
}
|
||||
});
|
||||
CFRunLoopAddObserver(CFRunLoopGetCurrent(), pre_wait_observer, kCFRunLoopCommonModes);
|
||||
return;
|
||||
|
||||
@@ -180,9 +180,9 @@ String OS_Web::get_name() const {
|
||||
return "Web";
|
||||
}
|
||||
|
||||
void OS_Web::add_frame_delay(bool p_can_draw) {
|
||||
void OS_Web::add_frame_delay(bool p_can_draw, bool p_wake_for_events) {
|
||||
#ifndef PROXY_TO_PTHREAD_ENABLED
|
||||
OS::add_frame_delay(p_can_draw);
|
||||
OS::add_frame_delay(p_can_draw, p_wake_for_events);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ public:
|
||||
|
||||
// Override default OS implementation which would block the main thread with delay_usec.
|
||||
// Implemented in web_main.cpp loop callback instead.
|
||||
void add_frame_delay(bool p_can_draw) override;
|
||||
void add_frame_delay(bool p_can_draw, bool p_wake_for_events) override;
|
||||
|
||||
void vibrate_handheld(int p_duration_ms, float p_amplitude) override;
|
||||
|
||||
|
||||
@@ -2494,7 +2494,21 @@ String OS_Windows::get_system_ca_certificates() {
|
||||
return certs;
|
||||
}
|
||||
|
||||
void OS_Windows::add_frame_delay(bool p_can_draw) {
|
||||
void OS_Windows::add_frame_delay(bool p_can_draw, bool p_wake_for_events) {
|
||||
if (p_wake_for_events) {
|
||||
uint64_t delay = get_frame_delay(p_can_draw);
|
||||
if (delay == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
DisplayServer *ds = DisplayServer::get_singleton();
|
||||
DisplayServerWindows *ds_win = Object::cast_to<DisplayServerWindows>(ds);
|
||||
if (ds_win) {
|
||||
MsgWaitForMultipleObjects(0, nullptr, false, Math::floor(double(delay) / 1000.0), QS_ALLINPUT);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -193,7 +193,7 @@ public:
|
||||
|
||||
virtual Error set_cwd(const String &p_cwd) override;
|
||||
|
||||
virtual void add_frame_delay(bool p_can_draw) override;
|
||||
virtual void add_frame_delay(bool p_can_draw, bool p_wake_for_events) override;
|
||||
virtual void delay_usec(uint32_t p_usec) const override;
|
||||
virtual uint64_t get_ticks_usec() const override;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user