gsdx:ogl: Call swap interval function on rendering thread

The swap interval function must be called on the same thread that
rendering takes place on. This fixes an issue where the turbo speed and
frame limiter hotkeys fail to disable vsync when the OpenGL renderer is
used.
This commit is contained in:
Jonathan Li 2017-08-21 23:02:29 +01:00
parent 12e7eac1b4
commit fecf8e3ed2
8 changed files with 26 additions and 14 deletions

View File

@ -199,5 +199,7 @@ void GSWndGL::SetVSync(int vsync)
else else
m_vsync = vsync; m_vsync = vsync;
SetSwapInterval(m_vsync); // The WGL/GLX/EGL swap interval function must be called on the rendering
// thread or else the change won't be properly applied.
m_vsync_change_requested = true;
} }

View File

@ -60,7 +60,8 @@ class GSWndGL : public GSWnd
{ {
protected: protected:
bool m_ctx_attached; bool m_ctx_attached;
int m_vsync; std::atomic<bool> m_vsync_change_requested;
std::atomic<int> m_vsync;
bool IsContextAttached() const { return m_ctx_attached; } bool IsContextAttached() const { return m_ctx_attached; }
void PopulateGlFunction(); void PopulateGlFunction();
@ -68,11 +69,11 @@ protected:
void FullContextInit(); void FullContextInit();
virtual void CreateContext(int major, int minor) = 0; virtual void CreateContext(int major, int minor) = 0;
virtual void SetSwapInterval(int vsync) = 0; virtual void SetSwapInterval() = 0;
virtual bool HasLateVsyncSupport() = 0; virtual bool HasLateVsyncSupport() = 0;
public: public:
GSWndGL() : m_ctx_attached(false), m_vsync(0) {}; GSWndGL() : m_ctx_attached(false), m_vsync_change_requested(false), m_vsync(0) {};
virtual ~GSWndGL() {}; virtual ~GSWndGL() {};
virtual bool Create(const string& title, int w, int h) = 0; virtual bool Create(const string& title, int w, int h) = 0;

View File

@ -235,15 +235,18 @@ GSVector4i GSWndEGL::GetClientRect()
return GSVector4i(0, 0, w, h); return GSVector4i(0, 0, w, h);
} }
void GSWndEGL::SetSwapInterval(int vsync) void GSWndEGL::SetSwapInterval()
{ {
// 0 -> disable vsync // 0 -> disable vsync
// n -> wait n frame // n -> wait n frame
eglSwapInterval(m_eglDisplay, vsync); eglSwapInterval(m_eglDisplay, m_vsync);
} }
void GSWndEGL::Flip() void GSWndEGL::Flip()
{ {
if (m_vsync_change_requested.exchange(false))
SetSwapInterval();
eglSwapBuffers(m_eglDisplay, m_eglSurface); eglSwapBuffers(m_eglDisplay, m_eglSurface);
} }

View File

@ -42,7 +42,7 @@ class GSWndEGL : public GSWndGL
void CreateContext(int major, int minor); void CreateContext(int major, int minor);
void BindAPI(); void BindAPI();
void SetSwapInterval(int vsync) final; void SetSwapInterval() final;
bool HasLateVsyncSupport() final { return false; } bool HasLateVsyncSupport() final { return false; }
void OpenEGLDisplay(); void OpenEGLDisplay();

View File

@ -238,18 +238,21 @@ bool GSWndOGL::SetWindowText(const char* title)
return true; return true;
} }
void GSWndOGL::SetSwapInterval(int vsync) void GSWndOGL::SetSwapInterval()
{ {
// m_swapinterval uses an integer as parameter // m_swapinterval uses an integer as parameter
// 0 -> disable vsync // 0 -> disable vsync
// n -> wait n frame // n -> wait n frame
if (m_swapinterval_ext) m_swapinterval_ext(m_NativeDisplay, m_NativeWindow, vsync); if (m_swapinterval_ext) m_swapinterval_ext(m_NativeDisplay, m_NativeWindow, m_vsync);
else if (m_swapinterval_mesa) m_swapinterval_mesa(vsync); else if (m_swapinterval_mesa) m_swapinterval_mesa(m_vsync);
else fprintf(stderr, "Failed to set VSync\n"); else fprintf(stderr, "Failed to set VSync\n");
} }
void GSWndOGL::Flip() void GSWndOGL::Flip()
{ {
if (m_vsync_change_requested.exchange(false))
SetSwapInterval();
glXSwapBuffers(m_NativeDisplay, m_NativeWindow); glXSwapBuffers(m_NativeDisplay, m_NativeWindow);
} }

View File

@ -38,7 +38,7 @@ class GSWndOGL final : public GSWndGL
void PopulateWndGlFunction(); void PopulateWndGlFunction();
void CreateContext(int major, int minor); void CreateContext(int major, int minor);
void SetSwapInterval(int vsync); void SetSwapInterval();
bool HasLateVsyncSupport() { return m_has_late_vsync; } bool HasLateVsyncSupport() { return m_has_late_vsync; }
public: public:

View File

@ -324,16 +324,19 @@ void* GSWndWGL::GetProcAddress(const char* name, bool opt)
//TODO: check extensions supported or not //TODO: check extensions supported or not
//FIXME : extension allocation //FIXME : extension allocation
void GSWndWGL::SetSwapInterval(int vsync) void GSWndWGL::SetSwapInterval()
{ {
// m_swapinterval uses an integer as parameter // m_swapinterval uses an integer as parameter
// 0 -> disable vsync // 0 -> disable vsync
// n -> wait n frame // n -> wait n frame
if (m_swapinterval) m_swapinterval(vsync); if (m_swapinterval) m_swapinterval(m_vsync);
} }
void GSWndWGL::Flip() void GSWndWGL::Flip()
{ {
if (m_vsync_change_requested.exchange(false))
SetSwapInterval();
SwapBuffers(m_NativeDisplay); SwapBuffers(m_NativeDisplay);
} }

View File

@ -38,7 +38,7 @@ class GSWndWGL : public GSWndGL
void CloseWGLDisplay(); void CloseWGLDisplay();
void OpenWGLDisplay(); void OpenWGLDisplay();
void SetSwapInterval(int vsync); void SetSwapInterval();
bool HasLateVsyncSupport() { return m_has_late_vsync; } bool HasLateVsyncSupport() { return m_has_late_vsync; }
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);