From 652c98a7beb8fc8a8aad5075a673caf21994a2ba Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sat, 16 Dec 2017 17:09:25 -0300 Subject: [PATCH] Add epic hack so vsync can be toggled in run-time from script. Fixes #14458. Call needs to be routed via visual server to reach the proper thread. --- core/os/os.cpp | 11 ++++++++++- core/os/os.h | 13 +++++++++++-- platform/osx/os_osx.h | 4 ++-- platform/osx/os_osx.mm | 6 +++--- platform/windows/os_windows.cpp | 6 +++--- platform/windows/os_windows.h | 4 ++-- platform/x11/os_x11.cpp | 6 +++--- platform/x11/os_x11.h | 4 ++-- servers/visual/visual_server_raster.cpp | 4 ++++ servers/visual/visual_server_raster.h | 2 ++ servers/visual/visual_server_wrap_mt.cpp | 10 ++++++++++ servers/visual/visual_server_wrap_mt.h | 6 ++++++ servers/visual_server.cpp | 1 + servers/visual_server.h | 2 ++ 14 files changed, 61 insertions(+), 18 deletions(-) diff --git a/core/os/os.cpp b/core/os/os.cpp index d81e70e6122..7010d449301 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -536,12 +536,21 @@ String OS::get_joy_guid(int p_device) const { void OS::set_context(int p_context) { } + +OS::SwitchVSyncCallbackInThread OS::switch_vsync_function = NULL; + void OS::set_use_vsync(bool p_enable) { + _use_vsync = p_enable; + if (switch_vsync_function) { //if a function was set, use function + switch_vsync_function(p_enable); + } else { //otherwise just call here + _set_use_vsync(p_enable); + } } bool OS::is_vsync_enabled() const { - return true; + return _use_vsync; } OS::PowerState OS::get_power_state() { diff --git a/core/os/os.h b/core/os/os.h index d9f7b91daad..2faaa6ab8f2 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -58,6 +58,7 @@ class OS { int _exit_code; int _orientation; bool _allow_hidpi; + bool _use_vsync; char *last_error; @@ -435,8 +436,16 @@ public: virtual void set_context(int p_context); - virtual void set_use_vsync(bool p_enable); - virtual bool is_vsync_enabled() const; + //amazing hack because OpenGL needs this to be set on a separate thread.. + //also core can't access servers, so a callback must be used + typedef void (*SwitchVSyncCallbackInThread)(bool); + + static SwitchVSyncCallbackInThread switch_vsync_function; + void set_use_vsync(bool p_enable); + bool is_vsync_enabled() const; + + //real, actual overridable function to switch vsync, which needs to be called from graphics thread if needed + virtual void _set_use_vsync(bool p_enable) {} virtual OS::PowerState get_power_state(); virtual int get_power_seconds_left(); diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index ede50a05bab..2381b856580 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -215,8 +215,8 @@ public: virtual bool _check_internal_feature_support(const String &p_feature); - virtual void set_use_vsync(bool p_enable); - virtual bool is_vsync_enabled() const; + virtual void _set_use_vsync(bool p_enable); + //virtual bool is_vsync_enabled() const; void run(); diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index f3809e6eedd..aab37cb59c2 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -2063,14 +2063,14 @@ Error OS_OSX::move_to_trash(const String &p_path) { return OK; } -void OS_OSX::set_use_vsync(bool p_enable) { +void OS_OSX::_set_use_vsync(bool p_enable) { CGLContextObj ctx = CGLGetCurrentContext(); if (ctx) { GLint swapInterval = p_enable ? 1 : 0; CGLSetParameter(ctx, kCGLCPSwapInterval, &swapInterval); } } - +/* bool OS_OSX::is_vsync_enabled() const { GLint swapInterval = 0; CGLContextObj ctx = CGLGetCurrentContext(); @@ -2079,7 +2079,7 @@ bool OS_OSX::is_vsync_enabled() const { } return swapInterval ? true : false; } - +*/ OS_OSX *OS_OSX::singleton = NULL; OS_OSX::OS_OSX() { diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 6cab683e837..d3fa2bbc0de 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -2288,19 +2288,19 @@ String OS_Windows::get_joy_guid(int p_device) const { return input->get_joy_guid_remapped(p_device); } -void OS_Windows::set_use_vsync(bool p_enable) { +void OS_Windows::_set_use_vsync(bool p_enable) { if (gl_context) gl_context->set_use_vsync(p_enable); } - +/* bool OS_Windows::is_vsync_enabled() const { if (gl_context) return gl_context->is_using_vsync(); return true; -} +}*/ OS::PowerState OS_Windows::get_power_state() { return power_manager->get_power_state(); diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index f2226a53a99..7c5490a0a40 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -275,8 +275,8 @@ public: virtual bool is_joy_known(int p_device); virtual String get_joy_guid(int p_device) const; - virtual void set_use_vsync(bool p_enable); - virtual bool is_vsync_enabled() const; + virtual void _set_use_vsync(bool p_enable); + //virtual bool is_vsync_enabled() const; virtual OS::PowerState get_power_state(); virtual int get_power_seconds_left(); diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 0c0bc1a8a3f..6616e473176 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -2306,11 +2306,11 @@ String OS_X11::get_joy_guid(int p_device) const { return input->get_joy_guid_remapped(p_device); } -void OS_X11::set_use_vsync(bool p_enable) { +void OS_X11::_set_use_vsync(bool p_enable) { if (context_gl) return context_gl->set_use_vsync(p_enable); } - +/* bool OS_X11::is_vsync_enabled() const { if (context_gl) @@ -2318,7 +2318,7 @@ bool OS_X11::is_vsync_enabled() const { return true; } - +*/ void OS_X11::set_context(int p_context) { XClassHint *classHint = XAllocClassHint(); diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index c8cea1e30ca..86f25918fd0 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -270,8 +270,8 @@ public: virtual void set_context(int p_context); - virtual void set_use_vsync(bool p_enable); - virtual bool is_vsync_enabled() const; + virtual void _set_use_vsync(bool p_enable); + //virtual bool is_vsync_enabled() const; virtual OS::PowerState get_power_state(); virtual int get_power_seconds_left(); diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index 6b527b5cd10..7bb7d04fcd6 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -181,6 +181,10 @@ void VisualServerRaster::set_debug_generate_wireframes(bool p_generate) { VSG::storage->set_debug_generate_wireframes(p_generate); } +void VisualServerRaster::call_set_use_vsync(bool p_enable) { + OS::get_singleton()->_set_use_vsync(p_enable); +} + VisualServerRaster::VisualServerRaster() { VSG::canvas = memnew(VisualServerCanvas); diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index a0e79e9d3e5..716c1754e1e 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -668,6 +668,8 @@ public: virtual bool has_os_feature(const String &p_feature) const; virtual void set_debug_generate_wireframes(bool p_generate); + virtual void call_set_use_vsync(bool p_enable); + VisualServerRaster(); ~VisualServerRaster(); diff --git a/servers/visual/visual_server_wrap_mt.cpp b/servers/visual/visual_server_wrap_mt.cpp index b86a0ae3f62..e55b7a93095 100644 --- a/servers/visual/visual_server_wrap_mt.cpp +++ b/servers/visual/visual_server_wrap_mt.cpp @@ -158,9 +158,19 @@ void VisualServerWrapMT::finish() { canvas_occluder_polygon_free_cached_ids(); } +void VisualServerWrapMT::set_use_vsync_callback(bool p_enable) { + + singleton_mt->call_set_use_vsync(p_enable); +} + +VisualServerWrapMT *VisualServerWrapMT::singleton_mt = NULL; + VisualServerWrapMT::VisualServerWrapMT(VisualServer *p_contained, bool p_create_thread) : command_queue(p_create_thread) { + singleton_mt = this; + OS::switch_vsync_function = set_use_vsync_callback; //as this goes to another thread, make sure it goes properly + visual_server = p_contained; create_thread = p_create_thread; thread = NULL; diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index cb6f67474ed..0f24521f5da 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -64,6 +64,8 @@ class VisualServerWrapMT : public VisualServer { //#define DEBUG_SYNC + static VisualServerWrapMT *singleton_mt; + #ifdef DEBUG_SYNC #define SYNC_DEBUG print_line("sync on: " + String(__FUNCTION__)); #else @@ -584,6 +586,10 @@ public: virtual bool has_feature(Features p_feature) const { return visual_server->has_feature(p_feature); } virtual bool has_os_feature(const String &p_feature) const { return visual_server->has_os_feature(p_feature); } + FUNC1(call_set_use_vsync, bool) + + static void set_use_vsync_callback(bool p_enable); + VisualServerWrapMT(VisualServer *p_contained, bool p_create_thread); ~VisualServerWrapMT(); diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index c0b53c2d9ac..42ecb82a460 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -1922,6 +1922,7 @@ VisualServer::VisualServer() { //ERR_FAIL_COND(singleton); singleton = this; + GLOBAL_DEF("rendering/vram_compression/import_s3tc", true); GLOBAL_DEF("rendering/vram_compression/import_etc", false); GLOBAL_DEF("rendering/vram_compression/import_etc2", true); diff --git a/servers/visual_server.h b/servers/visual_server.h index ff1f3cf0b97..23354c3d373 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -980,6 +980,8 @@ public: virtual void set_debug_generate_wireframes(bool p_generate) = 0; + virtual void call_set_use_vsync(bool p_enable) = 0; + VisualServer(); virtual ~VisualServer(); };