diff --git a/glxbackend.cpp b/glxbackend.cpp index b1aeecb4ba..627812fee4 100644 --- a/glxbackend.cpp +++ b/glxbackend.cpp @@ -41,6 +41,7 @@ namespace KWin GlxBackend::GlxBackend() : OpenGLBackend() , glxbuffer(None) + , haveSwapInterval(false) { init(); } @@ -91,8 +92,9 @@ void GlxBackend::init() glPlatform->printResults(); initGL(GlxPlatformInterface); // Check whether certain features are supported + haveSwapInterval = glXSwapIntervalMESA || glXSwapIntervalEXT || glXSwapIntervalSGI; if (options->isGlVSync()) { - if (glXGetVideoSync && glXSwapInterval && glXIsDirect(display(), ctxbuffer)) { + if (glXGetVideoSync && haveSwapInterval && glXIsDirect(display(), ctxbuffer)) { unsigned int sync; if (glXGetVideoSync(&sync) == 0) { if (glXWaitVideoSync(1, 0, &sync) == 0) { @@ -102,15 +104,15 @@ void GlxBackend::init() // However mesa/dri will return a range error (6) because deactivating the // swapinterval (as of today) seems completely unsupported setHasWaitSync(true); - glXSwapInterval(0); + setSwapInterval(0); } else qWarning() << "NO VSYNC! glXWaitVideoSync(1,0,&uint) isn't 0 but" << glXWaitVideoSync(1, 0, &sync); } else qWarning() << "NO VSYNC! glXGetVideoSync(&uint) isn't 0 but" << glXGetVideoSync(&sync); } else - qWarning() << "NO VSYNC! glXGetVideoSync, glXSwapInterval, glXIsDirect" << - bool(glXGetVideoSync) << bool(glXSwapInterval) << glXIsDirect(display(), ctxbuffer); + qWarning() << "NO VSYNC! glXGetVideoSync, haveSwapInterval, glXIsDirect" << + bool(glXGetVideoSync) << haveSwapInterval << glXIsDirect(display(), ctxbuffer); } if (glPlatform->isVirtualBox()) { // VirtualBox does not support glxQueryDrawable @@ -411,6 +413,16 @@ bool GlxBackend::initDrawableConfigs() return true; } +void GlxBackend::setSwapInterval(int interval) +{ + if (glXSwapIntervalEXT) + glXSwapIntervalEXT(display(), glxbuffer, interval); + else if (glXSwapIntervalMESA) + glXSwapIntervalMESA(interval); + else if (glXSwapIntervalSGI) + glXSwapIntervalSGI(interval); +} + #define VSYNC_DEBUG 0 void GlxBackend::waitSync() @@ -502,10 +514,10 @@ void GlxBackend::present() } } } else { - if (glXSwapInterval) { - glXSwapInterval(options->isGlVSync() ? 1 : 0); + if (haveSwapInterval) { + setSwapInterval(options->isGlVSync() ? 1 : 0); glXSwapBuffers(display(), glxbuffer); - glXSwapInterval(0); + setSwapInterval(0); startRenderTimer(); // this is important so we don't assume to be loosing frames in the compositor timing calculation } else { waitSync(); diff --git a/glxbackend.h b/glxbackend.h index ee08e8dcc6..ce46bacec2 100644 --- a/glxbackend.h +++ b/glxbackend.h @@ -57,6 +57,7 @@ private: void waitSync(); bool initRenderingContext(); bool initBufferConfigs(); + void setSwapInterval(int interval); GC gcroot; Drawable buffer; @@ -66,6 +67,7 @@ private: GLXFBConfig fbcbuffer; GLXDrawable glxbuffer; GLXContext ctxbuffer; + bool haveSwapInterval; friend class GlxTexture; }; diff --git a/libkwineffects/kwinglutils_funcs.cpp b/libkwineffects/kwinglutils_funcs.cpp index 4482328664..800bfb0ba7 100644 --- a/libkwineffects/kwinglutils_funcs.cpp +++ b/libkwineffects/kwinglutils_funcs.cpp @@ -65,7 +65,9 @@ glXCopySubBuffer_func glXCopySubBuffer; // video_sync extension functions glXGetVideoSync_func glXGetVideoSync; glXWaitVideoSync_func glXWaitVideoSync; -glXSwapInterval_func glXSwapInterval; +glXSwapIntervalMESA_func glXSwapIntervalMESA; +glXSwapIntervalEXT_func glXSwapIntervalEXT; +glXSwapIntervalSGI_func glXSwapIntervalSGI; // glActiveTexture glActiveTexture_func glActiveTexture; @@ -170,17 +172,18 @@ void glxResolveFunctions() glXWaitVideoSync = NULL; } - if (hasGLExtension("GLX_SGI_swap_control")) { - glXSwapInterval = (glXSwapInterval_func) getProcAddress("glXSwapIntervalSGI"); - } else if (hasGLExtension("GLX_EXT_swap_control")) { - glXSwapInterval = (glXSwapInterval_func) getProcAddress("glXSwapIntervalEXT"); - } else if (hasGLExtension("GLX_MESA_swap_control")) { - glXSwapInterval = (glXSwapInterval_func) getProcAddress("glXSwapIntervalMESA"); - } else if (hasGLExtension("GLX_OML_sync_control")) { - glXSwapInterval = (glXSwapInterval_func) getProcAddress("glXSwapIntervalOML"); - } else { - glXSwapInterval = NULL; - } + if (hasGLExtension("GLX_SGI_swap_control")) + glXSwapIntervalSGI = (glXSwapIntervalSGI_func) getProcAddress("glXSwapIntervalSGI"); + else + glXSwapIntervalSGI = NULL; + if (hasGLExtension("GLX_EXT_swap_control")) + glXSwapIntervalEXT = (glXSwapIntervalEXT_func) getProcAddress("glXSwapIntervalEXT"); + else + glXSwapIntervalEXT = NULL; + if (hasGLExtension("GLX_MESA_swap_control")) + glXSwapIntervalMESA = (glXSwapIntervalMESA_func) getProcAddress("glXSwapIntervalMESA"); + else + glXSwapIntervalMESA = NULL; } #endif diff --git a/libkwineffects/kwinglutils_funcs.h b/libkwineffects/kwinglutils_funcs.h index 968fb49b94..166da81c7b 100644 --- a/libkwineffects/kwinglutils_funcs.h +++ b/libkwineffects/kwinglutils_funcs.h @@ -205,10 +205,14 @@ extern KWIN_EXPORT glXCopySubBuffer_func glXCopySubBuffer; // video_sync extension functions typedef int (*glXGetVideoSync_func)(unsigned int *count); typedef int (*glXWaitVideoSync_func)(int divisor, int remainder, unsigned int *count); -typedef int (*glXSwapInterval_func)(int ratio); +typedef int (*glXSwapIntervalMESA_func)(unsigned int interval); +typedef void (*glXSwapIntervalEXT_func)(Display *dpy, GLXDrawable drawable, int interval); +typedef int (*glXSwapIntervalSGI_func)(int interval); extern KWIN_EXPORT glXGetVideoSync_func glXGetVideoSync; extern KWIN_EXPORT glXWaitVideoSync_func glXWaitVideoSync; -extern KWIN_EXPORT glXSwapInterval_func glXSwapInterval; +extern KWIN_EXPORT glXSwapIntervalMESA_func glXSwapIntervalMESA; +extern KWIN_EXPORT glXSwapIntervalEXT_func glXSwapIntervalEXT; +extern KWIN_EXPORT glXSwapIntervalSGI_func glXSwapIntervalSGI; // glActiveTexture typedef void (*glActiveTexture_func)(GLenum);