From 2420e46b449f4c8acdfe48c765ea52fc3e860de7 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sun, 5 Jun 2016 19:14:33 -0300 Subject: [PATCH] vsync support -works on windows -may not work on X11, if so please fix -OSX does not seem to support disabling vsync --- core/bind/core_bind.cpp | 11 +++++++++++ core/bind/core_bind.h | 3 +++ core/os/os.cpp | 8 ++++++++ core/os/os.h | 3 +++ drivers/gl_context/context_gl.h | 6 +++++- main/main.cpp | 3 +++ platform/windows/context_gl_win.cpp | 17 ++++++++++++++++- platform/windows/context_gl_win.h | 8 ++++++++ platform/windows/os_windows.cpp | 15 +++++++++++++++ platform/windows/os_windows.h | 3 +++ platform/x11/context_gl_x11.cpp | 11 +++++++++++ platform/x11/context_gl_x11.h | 4 ++++ platform/x11/os_x11.cpp | 14 ++++++++++++++ platform/x11/os_x11.h | 3 +++ 14 files changed, 107 insertions(+), 2 deletions(-) diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index addc26525e2..31c0c0e2080 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -436,6 +436,15 @@ Error _OS::set_thread_name(const String& p_name) { return Thread::set_name(p_name); }; +void _OS::set_use_vsync(bool p_enable) { + OS::get_singleton()->set_use_vsync(p_enable); +} + +bool _OS::is_vsnc_enabled() const { + + return OS::get_singleton()->is_vsnc_enabled(); +} + /* enum Weekday { @@ -1110,6 +1119,8 @@ void _OS::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_thread_name","name"),&_OS::set_thread_name); + ObjectTypeDB::bind_method(_MD("set_use_vsync","enable"),&_OS::set_use_vsync); + ObjectTypeDB::bind_method(_MD("is_vsnc_enabled"),&_OS::is_vsnc_enabled); BIND_CONSTANT( DAY_SUNDAY ); BIND_CONSTANT( DAY_MONDAY ); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index af89536c45a..441927940d4 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -282,6 +282,9 @@ public: Error set_thread_name(const String& p_name); + void set_use_vsync(bool p_enable); + bool is_vsnc_enabled() const; + static _OS *get_singleton() { return singleton; } _OS(); diff --git a/core/os/os.cpp b/core/os/os.cpp index 4daf41e68e8..e501bc2eb58 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -539,6 +539,14 @@ String OS::get_joy_guid(int p_device) const { void OS::set_context(int p_context) { } +void OS::set_use_vsync(bool p_enable) { + +} + +bool OS::is_vsnc_enabled() const{ + + return true; +} OS::OS() { last_error=NULL; diff --git a/core/os/os.h b/core/os/os.h index a1047bd48f4..c291d092508 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -420,6 +420,9 @@ public: virtual void set_context(int p_context); + virtual void set_use_vsync(bool p_enable); + virtual bool is_vsnc_enabled() const; + bool is_hidpi_allowed() const { return _allow_hidpi; } OS(); virtual ~OS(); diff --git a/drivers/gl_context/context_gl.h b/drivers/gl_context/context_gl.h index 1ea3662ada0..fd3bbee5de9 100644 --- a/drivers/gl_context/context_gl.h +++ b/drivers/gl_context/context_gl.h @@ -52,7 +52,11 @@ public: virtual void swap_buffers()=0; virtual Error initialize()=0; - + + virtual void set_use_vsync(bool p_use)=0; + virtual bool is_using_vsync() const=0; + + ContextGL(); diff --git a/main/main.cpp b/main/main.cpp index 2e30ed298a5..6cddea823a7 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -109,6 +109,7 @@ static String locale; static bool use_debug_profiler=false; static bool force_lowdpi=false; static int init_screen=-1; +static bool use_vsync=true; static String unescape_cmdline(const String& p_str) { @@ -726,6 +727,7 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas GLOBAL_DEF("display/fullscreen",video_mode.fullscreen); GLOBAL_DEF("display/resizable",video_mode.resizable); GLOBAL_DEF("display/borderless_window", video_mode.borderless_window); + use_vsync = GLOBAL_DEF("display/use_vsync", use_vsync); GLOBAL_DEF("display/test_width",0); GLOBAL_DEF("display/test_height",0); OS::get_singleton()->_pixel_snap=GLOBAL_DEF("display/use_2d_pixel_snap",false); @@ -876,6 +878,7 @@ Error Main::setup2() { OS::get_singleton()->set_window_position(init_custom_pos); } + OS::get_singleton()->set_use_vsync(use_vsync); register_core_singletons(); diff --git a/platform/windows/context_gl_win.cpp b/platform/windows/context_gl_win.cpp index ab66b81421b..fd9e895370d 100644 --- a/platform/windows/context_gl_win.cpp +++ b/platform/windows/context_gl_win.cpp @@ -96,6 +96,20 @@ static GLWrapperFuncPtr wrapper_get_proc_address(const char* p_function) { } */ +void ContextGL_Win::set_use_vsync(bool p_use) { + + if (wglSwapIntervalEXT) { + wglSwapIntervalEXT(p_use?1:0); + } + use_vsync=p_use; + +} + +bool ContextGL_Win::is_using_vsync() const { + + return use_vsync; +} + Error ContextGL_Win::initialize() { @@ -184,7 +198,7 @@ Error ContextGL_Win::initialize() { printf("Activated GL 3.1 context"); } - + wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) wglGetProcAddress ("wglSwapIntervalEXT"); // glWrapperInit(wrapper_get_proc_address); return OK; @@ -194,6 +208,7 @@ ContextGL_Win::ContextGL_Win(HWND hwnd,bool p_opengl_3_context) { opengl_3_context=p_opengl_3_context; hWnd=hwnd; + use_vsync=false; } ContextGL_Win::~ContextGL_Win() { diff --git a/platform/windows/context_gl_win.h b/platform/windows/context_gl_win.h index 055e0b2f517..e1ab6fb26a0 100644 --- a/platform/windows/context_gl_win.h +++ b/platform/windows/context_gl_win.h @@ -49,6 +49,8 @@ #include +typedef bool (APIENTRY *PFNWGLSWAPINTERVALEXTPROC) (int interval); + class ContextGL_Win : public ContextGL { HDC hDC; @@ -56,6 +58,10 @@ class ContextGL_Win : public ContextGL { unsigned int pixel_format; HWND hWnd; bool opengl_3_context; + bool use_vsync; + + + PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT; public: @@ -69,6 +75,8 @@ public: virtual Error initialize(); + virtual void set_use_vsync(bool p_use); + virtual bool is_using_vsync() const; ContextGL_Win(HWND hwnd,bool p_opengl_3_context); ~ContextGL_Win(); diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 65ee39f4da7..5e3dc438d0d 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -2269,6 +2269,21 @@ 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) { + + if (gl_context) + gl_context->set_use_vsync(p_enable); +} + +bool OS_Windows::is_vsnc_enabled() const{ + + if (gl_context) + return gl_context->is_using_vsync(); + + return true; +} + + OS_Windows::OS_Windows(HINSTANCE _hInstance) { key_event_pos=0; diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 6dd5b78bfdc..509d76abbf1 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -283,6 +283,9 @@ 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_vsnc_enabled() const; + OS_Windows(HINSTANCE _hInstance); ~OS_Windows(); diff --git a/platform/x11/context_gl_x11.cpp b/platform/x11/context_gl_x11.cpp index 9f987e13763..442adb5d888 100644 --- a/platform/x11/context_gl_x11.cpp +++ b/platform/x11/context_gl_x11.cpp @@ -176,6 +176,16 @@ int ContextGL_X11::get_window_height() { return xwa.height; } +void ContextGL_X11::set_use_vsync(bool p_use) { + GLXDrawable drawable = glXGetCurrentDrawable(); + glXSwapIntervalEXT(x11_display, drawable, p_use?1:0); + use_vsync=p_use; +} +bool ContextGL_X11::is_using_vsync() const { + + return use_vsync; +} + ContextGL_X11::ContextGL_X11(::Display *p_x11_display,::Window &p_x11_window,const OS::VideoMode& p_default_video_mode,bool p_opengl_3_context) : x11_window(p_x11_window) { @@ -189,6 +199,7 @@ ContextGL_X11::ContextGL_X11(::Display *p_x11_display,::Window &p_x11_window,con glx_minor=glx_major=0; p = memnew( ContextGL_X11_Private ); p->glx_context=0; + use_vsync=false; } diff --git a/platform/x11/context_gl_x11.h b/platform/x11/context_gl_x11.h index c77fb3e3334..4474542c0b3 100644 --- a/platform/x11/context_gl_x11.h +++ b/platform/x11/context_gl_x11.h @@ -55,6 +55,7 @@ class ContextGL_X11 : public ContextGL { bool direct_render; int glx_minor,glx_major; bool opengl_3_context; + bool use_vsync; public: virtual void release_current(); @@ -65,6 +66,9 @@ public: virtual Error initialize(); + virtual void set_use_vsync(bool p_use); + virtual bool is_using_vsync() const; + ContextGL_X11(::Display *p_x11_display,::Window &p_x11_window,const OS::VideoMode& p_default_video_mode,bool p_opengl_3_context); ~ContextGL_X11(); diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 66723c02959..b089436a17d 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -1952,6 +1952,20 @@ 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) { + if (context_gl) + return context_gl->set_use_vsync(p_enable); +} + +bool OS_X11::is_vsnc_enabled() const { + + if (context_gl) + return context_gl->is_using_vsync(); + + return true; +} + + void OS_X11::set_context(int p_context) { XClassHint* classHint = NULL; diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index 1369340b04a..311f26d4d3d 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -240,6 +240,9 @@ public: virtual void set_context(int p_context); + virtual void set_use_vsync(bool p_enable); + virtual bool is_vsnc_enabled() const; + void run(); OS_X11();