From ccf08113b90a1443701225a3821fc40ac7a71cb7 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 30 Oct 2010 14:01:31 +0200 Subject: [PATCH] Changed: #1145 Implement VSync under Linux --- .../src/3d/driver/opengl/driver_opengl.cpp | 50 ++++++++-- .../driver/opengl/driver_opengl_extension.cpp | 95 +++++++++++++++++++ .../driver/opengl/driver_opengl_extension.h | 30 ++++++ 3 files changed, 165 insertions(+), 10 deletions(-) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index 44eea09bd..7cc8e3f73 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -180,8 +180,6 @@ CDriverGL::CDriverGL() _PBuffer = NULL; _hRC = NULL; _hDC = NULL; - _NeedToRestaureGammaRamp = false; - _Interval = 1; #elif defined(NL_OS_MAC) @@ -216,6 +214,9 @@ CDriverGL::CDriverGL() #endif // NL_OS_UNIX + _NeedToRestaureGammaRamp = false; + _Interval = 1; + _win = EmptyWindow; _DestroyWindow = false; @@ -313,7 +314,6 @@ CDriverGL::CDriverGL() _VBHardProfiling= false; _CurVBHardLockCount= 0; _NumVBHardProfileFrame= 0; - _Interval = 1; _TexEnvReplace.setDefault(); _TexEnvReplace.Env.OpAlpha = CMaterial::Previous; @@ -355,14 +355,17 @@ bool CDriverGL::setupDisplay() // Driver caps. //============= // Retrieve the extensions for the current context. - NL3D::registerGlExtensions (_Extensions); + registerGlExtensions (_Extensions); vector lines; explode(_Extensions.toString(), string("\n"), lines); for(uint i = 0; i < lines.size(); i++) nlinfo("3D: %s", lines[i].c_str()); #ifdef NL_OS_WINDOWS - NL3D::registerWGlExtensions(_Extensions, _hDC); + registerWGlExtensions(_Extensions, _hDC); +#elif defined(NL_OS_MAC) +#elif defined(NL_OS_UNIX) + registerGLXExtensions(_Extensions, _dpy, DefaultScreen(_dpy)); #endif // NL_OS_WINDOWS // Check required extensions!! @@ -616,10 +619,8 @@ bool CDriverGL::setupDisplay() } } -#ifdef NL_OS_WINDOWS // Reset the vbl interval setSwapVBLInterval(_Interval); -#endif return true; } @@ -2036,13 +2037,40 @@ void CDriverGL::flush() void CDriverGL::setSwapVBLInterval(uint interval) { H_AUTO_OGL(CDriverGL_setSwapVBLInterval) -#ifdef NL_OS_WINDOWS + + if (!_Initialized) + return; + _Interval = interval; - if(_Extensions.WGLEXTSwapControl && _Initialized) + +#ifdef NL_OS_WINDOWS + if(_Extensions.WGLEXTSwapControl) { nwglSwapIntervalEXT(_Interval); } -#endif +#elif defined(NL_OS_MAC) +#elif defined(NL_OS_UNIX) + if (_win && _Extensions.GLXEXTSwapControl) + { + if (nglXSwapIntervalEXT(_dpy, _win, interval)) + { + nlwarning("Could not set swap interval"); + } + } + else if (_Extensions.GLXSGISwapControl) + { + if (nglXSwapIntervalSGI(interval)) + { + nlwarning("Could not set swap interval"); + } + } + else if (_Extensions.GLXMESASwapControl) + { + if (nglXSwapIntervalMESA(interval)) + { + nlwarning("Could not set swap interval"); + } + } } // *************************************************************************** @@ -2059,6 +2087,8 @@ uint CDriverGL::getSwapVBLInterval() #else return 1; #endif + + return _Interval; } // *************************************************************************** diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_extension.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_extension.cpp index 3c775a9a2..191d438cf 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_extension.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_extension.cpp @@ -440,6 +440,18 @@ PFNWGLGETSWAPINTERVALEXTPROC nwglGetSwapIntervalEXT; // WGL_ARB_extensions_string PFNWGLGETEXTENSIONSSTRINGARBPROC nwglGetExtensionsStringARB; + +#elif defined(NL_OS_MAC) +#elif defined(NL_OS_UNIX) + +// Swap control extensions +PFNGLXSWAPINTERVALEXTPROC nglXSwapIntervalEXT; + +PFNGLXSWAPINTERVALSGIPROC nglXSwapIntervalSGI; + +PFNGLXSWAPINTERVALMESAPROC nglXSwapIntervalMESA; +PFNGLXGETSWAPINTERVALMESAPROC nglXGetSwapIntervalMESA; + #endif // *************************************************************************** @@ -1410,6 +1422,46 @@ static bool setupWGLEXTSwapControl(const char *glext) return true; } +// ********************************* +static bool setupGLXEXTSwapControl(const char *glext) +{ + H_AUTO_OGL(setupGLXEXTSwapControl); + CHECK_EXT("GLX_EXT_swap_control"); + +#ifdef NL_OS_UNIX + CHECK_ADDRESS(PFNGLXSWAPINTERVALEXTPROC, glXSwapIntervalEXT); +#endif + + return true; +} + +// ********************************* +static bool setupGLXSGISwapControl(const char *glext) +{ + H_AUTO_OGL(setupGLXSGISwapControl); + CHECK_EXT("GLX_SGI_swap_control"); + +#ifdef NL_OS_UNIX + CHECK_ADDRESS(PFNGLXSWAPINTERVALSGIPROC, glXSwapIntervalSGI); +#endif + + return true; +} + +// ********************************* +static bool setupGLXMESASwapControl(const char *glext) +{ + H_AUTO_OGL(setupGLXMESASwapControl); + CHECK_EXT("GLX_MESA_swap_control"); + +#ifdef NL_OS_UNIX + CHECK_ADDRESS(PFNGLXSWAPINTERVALMESAPROC, glXSwapIntervalMESA); + CHECK_ADDRESS(PFNGLXGETSWAPINTERVALMESAPROC, glXGetSwapIntervalMESA); +#endif + + return true; +} + #ifdef NL_OS_WINDOWS // *************************************************************************** bool registerWGlExtensions(CGlExtensions &ext, HDC hDC) @@ -1452,6 +1504,49 @@ bool registerWGlExtensions(CGlExtensions &ext, HDC hDC) return true; } +#elif defined(NL_OS_MAC) +#elif defined(NL_OS_UNIX) +// *************************************************************************** +bool registerGlXExtensions(CGlExtensions &ext, Display *dpy, sint screen) +{ + H_AUTO_OGL(registerGlXExtensions); + + // Get extension string + const char *glext = glXQueryExtensionsString(dpy, screen); + if (glext == NULL) + { + nlwarning ("glXQueryExtensionsString failed"); + return false; + } + + nldebug("3D: Available GLX Extensions:"); + + if (DebugLog) + { + vector exts; + explode(string(glext), string(" "), exts); + for(uint i = 0; i < exts.size(); i++) + { + if(i%5==0) DebugLog->displayRaw("3D: "); + DebugLog->displayRaw(string(exts[i]+" ").c_str()); + if(i%5==4) DebugLog->displayRaw("\n"); + } + DebugLog->displayRaw("\n"); + } + + // Check for pbuffer +// ext.WGLARBPBuffer= setupWGLARBPBuffer(glext); + + // Check for pixel format +// ext.WGLARBPixelFormat= setupWGLARBPixelFormat(glext); + + // Check for swap control + ext.GLXEXTSwapControl= setupGLXEXTSwapControl(glext); + ext.GLXSGISwapControl= setupGLXSGISwapControl(glext); + ext.GLXMESASwapControl= setupGLXMESASwapControl(glext); + + return true; +} #endif // NL_OS_WINDOWS } diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_extension.h b/code/nel/src/3d/driver/opengl/driver_opengl_extension.h index 134e0bd6b..e1b897dd2 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_extension.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl_extension.h @@ -34,6 +34,7 @@ # include # include // Please download it from http://www.opengl.org/registry/ # include +# include #endif // NL_OS_UNIX #ifndef GL_GLEXT_VERSION @@ -93,6 +94,11 @@ struct CGlExtensions bool WGLARBPixelFormat; bool WGLEXTSwapControl; + // GLX extensions, true if supported + bool GLXEXTSwapControl; + bool GLXSGISwapControl; + bool GLXMESASwapControl; + // ATI Extensions. bool ATIVertexArrayObject; bool ATIMapObjectBuffer; @@ -147,6 +153,9 @@ public: WGLARBPBuffer= false; WGLARBPixelFormat= false; WGLEXTSwapControl= false; + GLXEXTSwapControl= false; + GLXSGISwapControl= false; + GLXMESASwapControl= false; EXTBlendColor= false; ATIVertexArrayObject= false; ATIEnvMapBumpMap = false; @@ -225,6 +234,11 @@ public: result += WGLARBPBuffer ? "WGLARBPBuffer " : ""; result += WGLARBPixelFormat ? "WGLARBPixelFormat " : ""; result += WGLEXTSwapControl ? "WGLEXTSwapControl " : ""; +#elif defined(NL_OS_MAC) +#elif defined(NL_OS_UNIX) + result += GLXEXTSwapControl ? "GLXEXTSwapControl " : ""; + result += GLXSGISwapControl ? "GLXSGISwapControl " : ""; + result += GLXMESASwapControl ? "GLXMESASwapControl " : ""; #endif result += "\n Array/VBO: "; @@ -249,6 +263,10 @@ public: #ifdef NL_OS_WINDOWS /// This function will test and register WGL functions before than the gl context is created bool registerWGlExtensions(CGlExtensions &ext, HDC hDC); +#elif defined(NL_OS_MAC) +#elif defined(NL_OS_UNIX) +/// This function will test and register GLX functions before than the gl context is created +bool registerGlXExtensions(CGlExtensions &ext, Display *dpy, sint screen); #endif // NL_OS_WINDOWS /// This function test and register the extensions for the current GL context. @@ -674,6 +692,18 @@ extern PFNWGLGETSWAPINTERVALEXTPROC nwglGetSwapIntervalEXT; // WGL_ARB_extensions_string extern PFNWGLGETEXTENSIONSSTRINGARBPROC nwglGetExtensionsStringARB; +#elif defined(NL_OS_MAC) +#elif defined(NL_OS_UNIX) + +// Swap control extensions +//=========================== +extern PFNGLXSWAPINTERVALEXTPROC nglXSwapIntervalEXT; + +extern PFNGLXSWAPINTERVALSGIPROC nglXSwapIntervalSGI; + +extern PFNGLXSWAPINTERVALMESAPROC nglXSwapIntervalMESA; +extern PFNGLXGETSWAPINTERVALMESAPROC nglXGetSwapIntervalMESA; + #endif // GL_EXT_framebuffer_object