From a15624dcc5fe1a9ce0df8380ea22c2d6df5eb27a Mon Sep 17 00:00:00 2001 From: Roman Gilg Date: Thu, 9 Jan 2020 18:18:25 +0100 Subject: [PATCH] Revert "[platforms/x11/standalone] Remove SGI swap control and video sync" This reverts commit 285adc1950c98a197ff51d2e82ec928e404a0533. See: https://mail.kde.org/pipermail/kwin/2020-January/002999.html --- .../platforms/x11/standalone/glxbackend.cpp | 39 ++++++++++++++++--- plugins/platforms/x11/standalone/glxbackend.h | 3 ++ 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/plugins/platforms/x11/standalone/glxbackend.cpp b/plugins/platforms/x11/standalone/glxbackend.cpp index e632109543..611d3e3996 100644 --- a/plugins/platforms/x11/standalone/glxbackend.cpp +++ b/plugins/platforms/x11/standalone/glxbackend.cpp @@ -212,6 +212,7 @@ void GlxBackend::init() m_haveMESACopySubBuffer = hasExtension(QByteArrayLiteral("GLX_MESA_copy_sub_buffer")); m_haveMESASwapControl = hasExtension(QByteArrayLiteral("GLX_MESA_swap_control")); m_haveEXTSwapControl = hasExtension(QByteArrayLiteral("GLX_EXT_swap_control")); + m_haveSGISwapControl = hasExtension(QByteArrayLiteral("GLX_SGI_swap_control")); // only enable Intel swap event if env variable is set, see BUG 342582 m_haveINTELSwapEvent = hasExtension(QByteArrayLiteral("GLX_INTEL_swap_event")) && qgetenv("KWIN_USE_INTEL_SWAP_EVENT") == QByteArrayLiteral("1"); @@ -221,7 +222,7 @@ void GlxBackend::init() glXSelectEvent(display(), glxWindow, GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK); } - haveSwapInterval = m_haveMESASwapControl || m_haveEXTSwapControl; + haveSwapInterval = m_haveMESASwapControl || m_haveEXTSwapControl || m_haveSGISwapControl; setSupportsBufferAge(false); @@ -233,15 +234,23 @@ void GlxBackend::init() } setSyncsToVBlank(false); - setBlocksForRetrace(true); + setBlocksForRetrace(false); + haveWaitSync = false; const bool wantSync = options->glPreferBufferSwap() != Options::NoSwapEncourage; if (wantSync && glXIsDirect(display(), ctx)) { if (haveSwapInterval) { // glXSwapInterval is preferred being more reliable setSwapInterval(1); setSyncsToVBlank(true); - } else { - qCWarning(KWIN_X11STANDALONE) << "NO VSYNC! glSwapInterval is not supported"; - } + } else if (hasExtension(QByteArrayLiteral("GLX_SGI_video_sync"))) { + unsigned int sync; + if (glXGetVideoSyncSGI(&sync) == 0 && glXWaitVideoSyncSGI(1, 0, &sync) == 0) { + setSyncsToVBlank(true); + setBlocksForRetrace(true); + haveWaitSync = true; + } else + qCWarning(KWIN_X11STANDALONE) << "NO VSYNC! glXSwapInterval is not supported, glXWaitVideoSync is supported but broken"; + } else + qCWarning(KWIN_X11STANDALONE) << "NO VSYNC! neither glSwapInterval nor glXWaitVideoSync are supported"; } else { // disable v-sync (if possible) setSwapInterval(0); @@ -678,6 +687,25 @@ void GlxBackend::setSwapInterval(int interval) glXSwapIntervalEXT(display(), glxWindow, interval); else if (m_haveMESASwapControl) glXSwapIntervalMESA(interval); + else if (m_haveSGISwapControl) + glXSwapIntervalSGI(interval); +} + +void GlxBackend::waitSync() +{ + // NOTE that vsync has no effect with indirect rendering + if (haveWaitSync) { + uint sync; +#if 0 + // TODO: why precisely is this important? + // the sync counter /can/ perform multiple steps during glXGetVideoSync & glXWaitVideoSync + // but this only leads to waiting for two frames??!? + glXGetVideoSync(&sync); + glXWaitVideoSync(2, (sync + 1) % 2, &sync); +#else + glXWaitVideoSyncSGI(1, 0, &sync); +#endif + } } void GlxBackend::present() @@ -696,6 +724,7 @@ void GlxBackend::present() if (haveSwapInterval) { glXSwapBuffers(display(), glxWindow); } else { + waitSync(); glXSwapBuffers(display(), glxWindow); } if (supportsBufferAge()) { diff --git a/plugins/platforms/x11/standalone/glxbackend.h b/plugins/platforms/x11/standalone/glxbackend.h index ec55ac49b1..33914337fb 100644 --- a/plugins/platforms/x11/standalone/glxbackend.h +++ b/plugins/platforms/x11/standalone/glxbackend.h @@ -86,6 +86,7 @@ private: bool initBuffer(); bool checkVersion(); void initExtensions(); + void waitSync(); bool initRenderingContext(); bool initFbConfig(); void initVisualDepthHashTable(); @@ -112,8 +113,10 @@ private: bool m_haveMESACopySubBuffer = false; bool m_haveMESASwapControl = false; bool m_haveEXTSwapControl = false; + bool m_haveSGISwapControl = false; bool m_haveINTELSwapEvent = false; bool haveSwapInterval = false; + bool haveWaitSync = false; Display *m_x11Display; friend class GlxTexture; };