You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-15 13:51:40 +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();
|
const uint32_t frame_delay = Engine::get_singleton()->get_frame_delay();
|
||||||
if (frame_delay) {
|
if (frame_delay) {
|
||||||
// Add fixed frame delay to decrease CPU/GPU usage. This doesn't take
|
// 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 double get_unix_time() 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 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;
|
virtual uint64_t get_ticks_usec() const = 0;
|
||||||
uint64_t get_ticks_msec() const;
|
uint64_t get_ticks_msec() const;
|
||||||
|
|||||||
@@ -4855,11 +4855,9 @@ bool Main::iteration() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SceneTree *scene_tree = SceneTree::get_singleton();
|
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(), wake_for_events);
|
||||||
OS::get_singleton()->add_frame_delay(DisplayServer::get_singleton()->window_can_draw());
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
if (auto_build_solutions) {
|
if (auto_build_solutions) {
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ protected:
|
|||||||
|
|
||||||
JoypadApple *joypad_apple = nullptr;
|
JoypadApple *joypad_apple = nullptr;
|
||||||
MainLoop *main_loop = nullptr;
|
MainLoop *main_loop = nullptr;
|
||||||
|
CFRunLoopTimerRef wait_timer = nil;
|
||||||
|
|
||||||
virtual void initialize_core() override;
|
virtual void initialize_core() override;
|
||||||
virtual void initialize() override;
|
virtual void initialize() override;
|
||||||
@@ -75,6 +76,8 @@ protected:
|
|||||||
virtual void delete_main_loop() override;
|
virtual void delete_main_loop() override;
|
||||||
|
|
||||||
public:
|
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 void set_cmdline_platform_args(const List<String> &p_args);
|
||||||
virtual List<String> get_cmdline_platform_args() const override;
|
virtual List<String> get_cmdline_platform_args() const override;
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,28 @@
|
|||||||
#include <os/log.h>
|
#include <os/log.h>
|
||||||
#include <sys/sysctl.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() {
|
void OS_MacOS::initialize() {
|
||||||
crash_handler.initialize();
|
crash_handler.initialize();
|
||||||
|
|
||||||
@@ -995,8 +1017,9 @@ void OS_MacOS_NSApp::start_main() {
|
|||||||
ERR_PRINT("NSException: " + String::utf8([exception reason].UTF8String));
|
ERR_PRINT("NSException: " + String::utf8([exception reason].UTF8String));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (wait_timer == nil) {
|
||||||
CFRunLoopWakeUp(CFRunLoopGetCurrent()); // Prevent main loop from sleeping.
|
CFRunLoopWakeUp(CFRunLoopGetCurrent()); // Prevent main loop from sleeping.
|
||||||
|
}
|
||||||
});
|
});
|
||||||
CFRunLoopAddObserver(CFRunLoopGetCurrent(), pre_wait_observer, kCFRunLoopCommonModes);
|
CFRunLoopAddObserver(CFRunLoopGetCurrent(), pre_wait_observer, kCFRunLoopCommonModes);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -180,9 +180,9 @@ String OS_Web::get_name() const {
|
|||||||
return "Web";
|
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
|
#ifndef PROXY_TO_PTHREAD_ENABLED
|
||||||
OS::add_frame_delay(p_can_draw);
|
OS::add_frame_delay(p_can_draw, p_wake_for_events);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ public:
|
|||||||
|
|
||||||
// Override default OS implementation which would block the main thread with delay_usec.
|
// Override default OS implementation which would block the main thread with delay_usec.
|
||||||
// Implemented in web_main.cpp loop callback instead.
|
// 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;
|
void vibrate_handheld(int p_duration_ms, float p_amplitude) override;
|
||||||
|
|
||||||
|
|||||||
@@ -2494,7 +2494,21 @@ String OS_Windows::get_system_ca_certificates() {
|
|||||||
return certs;
|
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();
|
const uint32_t frame_delay = Engine::get_singleton()->get_frame_delay();
|
||||||
if (frame_delay) {
|
if (frame_delay) {
|
||||||
// Add fixed frame delay to decrease CPU/GPU usage. This doesn't take
|
// 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 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 void delay_usec(uint32_t p_usec) const override;
|
||||||
virtual uint64_t get_ticks_usec() const override;
|
virtual uint64_t get_ticks_usec() const override;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user