Commit 6d20d19f authored by Vlad Zahorodnii's avatar Vlad Zahorodnii
Browse files

platforms/x11: Always set swap interval to 1

With the new compositing scheduling, we want the screen to be redrawn as
close as possible to the next vblank. Furthermore, compositing is no
longer driven by a timer. This change removes the NoSwapEncourage swap
strategy as it doesn't make sense now, in addition to that it just does
not work on Wayland.
parent 2e3a6b72
......@@ -227,11 +227,6 @@ Alternatively, you might want to use the XRender backend instead.</string>
</item>
<item row="12" column="1">
<widget class="QComboBox" name="kcfg_glPreferBufferSwap">
<item>
<property name="text">
<string>Never</string>
</property>
</item>
<item>
<property name="text">
<string>Automatic</string>
......
......@@ -45,7 +45,6 @@
<entry name="glPreferBufferSwap" key="GLPreferBufferSwap" type="Enum">
<default>AutoSwapStrategy</default>
<choices>
<choice name="NoSwapEncourage" value="n" />
<choice name="AutoSwapStrategy" value="a" />
<choice name="ExtendDamage" value="e" />
<choice name="PaintFullScreen" value="p" />
......
......@@ -130,15 +130,15 @@ void KWinCompositingKCM::init()
// tearing prevention
connect(m_form.kcfg_glPreferBufferSwap, currentIndexChangedSignal, this,
[this](int index) {
if (index == 2) {
if (index == 1) {
// only when cheap - tearing
m_form.tearingWarning->setText(i18n("\"Only when cheap\" only prevents tearing for full screen changes like a video."));
m_form.tearingWarning->animatedShow();
} else if (index == 3) {
} else if (index == 2) {
// full screen repaints
m_form.tearingWarning->setText(i18n("\"Full screen repaints\" can cause performance problems."));
m_form.tearingWarning->animatedShow();
} else if (index == 4) {
} else if (index == 3) {
// re-use screen content
m_form.tearingWarning->setText(i18n("\"Re-use screen content\" causes severe performance problems on MESA drivers."));
m_form.tearingWarning->animatedShow();
......
......@@ -6,6 +6,8 @@ install(PROGRAMS kwin-5.18-move-animspeed.py
DESTINATION ${KDE_INSTALL_KCONFUPDATEDIR})
install(PROGRAMS kwin-5.21-desktop-grid-click-behavior.py
DESTINATION ${KDE_INSTALL_KCONFUPDATEDIR})
install(PROGRAMS kwin-5.21-no-swap-encourage.py
DESTINATION ${KDE_INSTALL_KCONFUPDATEDIR})
install(FILES kwinrules.upd
DESTINATION ${KDE_INSTALL_KCONFUPDATEDIR})
......
#!/usr/bin/env python3
import fileinput
for line in fileinput.input():
if not line.startswith("GLPreferBufferSwap="):
continue
value = line[len("GLPreferBufferSwap="):].strip()
if value != "n":
continue
print("# DELETE GLPreferBufferSwap") # will use the default swap strategy
......@@ -43,3 +43,9 @@ Id=desktop-grid-click-behavior
File=kwinrc
Group=Effect-DesktopGrid
Script=kwin-5.21-desktop-grid-click-behavior.py,python3
# Remove GLPreferBufferSwap if it has a value of "n"
Id=no-swap-encourage
File=kwinrc
Group=Compositing
File=kwin-5.21-no-swap-encourage.py,python3
......@@ -896,7 +896,7 @@ void Options::reloadCompositingSettings(bool force)
if (!s.isEmpty())
c = s.at(0).toLatin1();
if (c != 'a' && c != 'c' && c != 'p' && c != 'e')
c = 0;
c = Options::defaultGlPreferBufferSwap();
setGlPreferBufferSwap(c);
m_xrenderSmoothScale = config.readEntry("XRenderSmoothScale", false);
......
......@@ -590,7 +590,7 @@ public:
return m_glPlatformInterface;
}
enum GlSwapStrategy { NoSwapEncourage = 0, CopyFrontBuffer = 'c', PaintFullScreen = 'p', ExtendDamage = 'e', AutoSwapStrategy = 'a' };
enum GlSwapStrategy { CopyFrontBuffer = 'c', PaintFullScreen = 'p', ExtendDamage = 'e', AutoSwapStrategy = 'a' };
Q_ENUM(GlSwapStrategy)
GlSwapStrategy glPreferBufferSwap() const {
return m_glPreferBufferSwap;
......
......@@ -102,20 +102,15 @@ void EglOnXBackend::init()
if (surfaceHasSubPost) {
qCDebug(KWIN_CORE) << "EGL implementation and surface support eglPostSubBufferNV, let's use it";
if (options->glPreferBufferSwap() != Options::NoSwapEncourage) {
// check if swap interval 1 is supported
EGLint val;
eglGetConfigAttrib(eglDisplay(), config(), EGL_MAX_SWAP_INTERVAL, &val);
if (val >= 1) {
if (eglSwapInterval(eglDisplay(), 1)) {
qCDebug(KWIN_CORE) << "Enabled v-sync";
}
} else {
qCWarning(KWIN_CORE) << "Cannot enable v-sync as max. swap interval is" << val;
// check if swap interval 1 is supported
EGLint val;
eglGetConfigAttrib(eglDisplay(), config(), EGL_MAX_SWAP_INTERVAL, &val);
if (val >= 1) {
if (eglSwapInterval(eglDisplay(), 1)) {
qCDebug(KWIN_CORE) << "Enabled v-sync";
}
} else {
// disable v-sync
eglSwapInterval(eglDisplay(), 0);
qCWarning(KWIN_CORE) << "Cannot enable v-sync as max. swap interval is" << val;
}
} else {
/* In the GLX backend, we fall back to using glCopyPixels if we have no extension providing support for partial screen updates.
......
......@@ -224,17 +224,12 @@ void GlxBackend::init()
m_haveINTELSwapEvent = false;
}
const bool wantSync = options->glPreferBufferSwap() != Options::NoSwapEncourage;
if (wantSync && glXIsDirect(display(), ctx)) {
if (haveSwapInterval) { // glXSwapInterval is preferred being more reliable
setSwapInterval(1);
} else {
qCWarning(KWIN_X11STANDALONE) << "glSwapInterval is unsupported";
}
if (haveSwapInterval) {
setSwapInterval(1);
} else {
// disable v-sync (if possible)
setSwapInterval(0);
qCWarning(KWIN_X11STANDALONE) << "glSwapInterval is unsupported";
}
if (glPlatform->isVirtualBox()) {
// VirtualBox does not support glxQueryDrawable
// this should actually be in kwinglutils_funcs, but QueryDrawable seems not to be provided by an extension
......
  • This broke Zoom screen sharing for me. Previously I had disabled vsync because screen sharing through Zoom caused terrible screen flickering for people watching my screen. No I can't turn it off and thus I cannot use screen sharing with Zoom.

  • It doesn't seem like a correct way to fix the issue. But if you want to disable sync'ing to vblank, you can set an environment variable, see https://invent.kde.org/plasma/kwin/-/wikis/Environment-Variables#kwin_x11_no_sync_to_vblank

  • What would be the correct way to fix the issue?

    I can no longer use OBS to record clips because of the tearing and in the OBS forum the recommended solution is to disable VSync.

    I can also set the rendering backend to XRender on the composition settings to prevent the flickering, but it doesn't have transparency.

  • If you want to disable vsync, try setting the following environment variables

    KWIN_X11_REFRESH_RATE=60000
    KWIN_X11_NO_SYNC_TO_VBLANK=1
    KWIN_X11_FORCE_SOFTWARE_VSYNC=1

    However, disabling vsync to fix flickering in obs doesn't sound right. I suggest to report this issue to OBS developers.

  • Thanks for the quick response!

    I'll report the issue with OBS developers.

  • I agree with Vlad that env variables are not a solution. I run into the issue that Spectacle will show screenshots from 2 to 4 hours prior but not what was currently expected. If I disable the compositor it works fine but breaks quite a few other things. I put in the env variables to disable vsync and I've had no issues. Is there a better solution?

  • yes, i also think an option should still be readily available in the dropdown menu.

    im on x11 with nvidia-proprietary drivers and 2 screens, im using https://wiki.archlinux.org/title/NVIDIA/Troubleshooting#Multi-monitor to completely eliminate screen-tearing without outside vsync, but having both ForceCompositionPipeline=On and kwin vsync makes certain games have extremely bizzare FPS and lag issues, disabling kwin's vsync with the environment variables eliminates that.

    it should at least continue to be an option for x11

  • I agree that the option to keep vsync off on X11 should be kept. I don't have any application specific issues but I greatly prefer screen tearing over the experience of having the desktop drop frames constantly which makes mouse movement, animations and programs feel clunky and unresponsive.

  • This is a definite downgrade. The dropdown menu being readily available was good, and the KWin "Suspend Compositing" shortcut was even faster, now none of them work.

Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment