From 750c1949597179a1bb60daaad4fa71d80ecc7e47 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 26 Sep 2016 01:38:25 +0200 Subject: [PATCH] - changed order of SwapBuffers and glFinish call. The new order with glFinish coming last is recommended by OpenGL and it fixes a stalling problem with portals and camera textures visible at the same time. - check and use WGL_EXT_swap_control_tear extension. The above change makes the system always wait for a full vsync with a wglSwapInterval of 1, so it now uses the official extension that enables adaptive vsync. Hopefully this also works on the cards where the old setup did not. --- src/gl/scene/gl_portal.cpp | 6 +++--- src/gl/system/gl_framebuffer.cpp | 2 +- src/win32/win32gliface.cpp | 34 +++++++++++++++++++++++++++----- src/win32/win32gliface.h | 1 + 4 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index f34b5e23f..4a7fa9d7a 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -176,12 +176,12 @@ void GLPortal::DrawPortalStencil() bool GLPortal::Start(bool usestencil, bool doquery) { rendered_portals++; - PortalAll.Clock(); +// PortalAll.Clock(); if (usestencil) { if (!gl_portals) { - PortalAll.Unclock(); +// PortalAll.Unclock(); return false; } @@ -297,7 +297,7 @@ bool GLPortal::Start(bool usestencil, bool doquery) GLRenderer->mCurrentPortal = this; if (PrevPortal != NULL) PrevPortal->PushState(); - PortalAll.Unclock(); +// PortalAll.Unclock(); return true; } diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 94eba0817..08aca521f 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -209,13 +209,13 @@ void OpenGLFrameBuffer::Swap() { Finish.Reset(); Finish.Clock(); - glFinish(); if (needsetgamma) { //DoSetGamma(); needsetgamma = false; } SwapBuffers(); + glFinish(); Finish.Unclock(); swapped = true; FHardwareTexture::UnbindAll(); diff --git a/src/win32/win32gliface.cpp b/src/win32/win32gliface.cpp index 7ca001e1e..5d68d8427 100644 --- a/src/win32/win32gliface.cpp +++ b/src/win32/win32gliface.cpp @@ -37,7 +37,9 @@ extern int NewWidth, NewHeight, NewBits, DisplayBits; // these get used before GLEW is initialized so we have to use separate pointers with different names PFNWGLCHOOSEPIXELFORMATARBPROC myWglChoosePixelFormatARB; // = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); PFNWGLCREATECONTEXTATTRIBSARBPROC myWglCreateContextAttribsARB; -PFNWGLSWAPINTERVALEXTPROC vsyncfunc; +PFNWGLSWAPINTERVALEXTPROC myWglSwapIntervalExtProc; + + CUSTOM_CVAR(Bool, gl_debug, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) @@ -933,10 +935,32 @@ Win32GLFrameBuffer::Win32GLFrameBuffer(void *hMonitor, int width, int height, in vid_renderer = 0; return; } - - vsyncfunc = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); - HDC hDC = GetDC(Window); + const char *wglext = nullptr; + + myWglSwapIntervalExtProc = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); + auto myWglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB"); + if (myWglGetExtensionsStringARB) + { + wglext = myWglGetExtensionsStringARB(hDC); + } + else + { + auto myWglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)wglGetProcAddress("wglGetExtensionsStringEXT"); + if (myWglGetExtensionsStringEXT) + { + wglext = myWglGetExtensionsStringEXT(); + } + } + SwapInterval = 1; + if (wglext != nullptr) + { + if (strstr(wglext, "WGL_EXT_swap_control_tear")) + { + SwapInterval = -1; + } + } + m_supportsGamma = !!GetDeviceGammaRamp(hDC, (void *)m_origGamma); ReleaseDC(Window, hDC); } @@ -1091,7 +1115,7 @@ void Win32GLFrameBuffer::ReleaseResources () void Win32GLFrameBuffer::SetVSync (bool vsync) { - if (vsyncfunc != NULL) vsyncfunc(vsync ? 1 : 0); + if (myWglSwapIntervalExtProc != NULL) myWglSwapIntervalExtProc(vsync ? SwapInterval : 0); } void Win32GLFrameBuffer::SwapBuffers() diff --git a/src/win32/win32gliface.h b/src/win32/win32gliface.h index 6320e2903..e767073c4 100644 --- a/src/win32/win32gliface.h +++ b/src/win32/win32gliface.h @@ -148,6 +148,7 @@ protected: int m_Lock; char m_displayDeviceNameBuffer[CCHDEVICENAME]; char *m_displayDeviceName; + int SwapInterval; friend class Win32GLVideo;