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
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:
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; }
void PopulateGlFunction();
@ -68,11 +69,11 @@ protected:
void FullContextInit();
virtual void CreateContext(int major, int minor) = 0;
virtual void SetSwapInterval(int vsync) = 0;
virtual void SetSwapInterval() = 0;
virtual bool HasLateVsyncSupport() = 0;
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 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);
}
void GSWndEGL::SetSwapInterval(int vsync)
void GSWndEGL::SetSwapInterval()
{
// 0 -> disable vsync
// n -> wait n frame
eglSwapInterval(m_eglDisplay, vsync);
eglSwapInterval(m_eglDisplay, m_vsync);
}
void GSWndEGL::Flip()
{
if (m_vsync_change_requested.exchange(false))
SetSwapInterval();
eglSwapBuffers(m_eglDisplay, m_eglSurface);
}

View File

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

View File

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

View File

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

View File

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

View File

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