I have a Tearing prevention setting set to "Full screen repaints" which is working great. If I connect or disconnect external monitor, this setting is not applied anymore although I can still see it set correctly in settings. But now I am experiencing the screen tearing until I restart kwin or re-apply the compositor settings. Reproducible: Always Steps to Reproduce: 1. Go to System settings -> Compositor and set Tearing prevention ("vsync") to "Never" 2. Ensure you can actually spot the tearing now - e.g. when playing video 3. Set Tearing prevention to "Full screen repaints" 4. Ensure it fixed the tearing 5. Connect external monitor 6. Play the same video and observe Actual Results: Screen tearing is visible again. Expected Results: Tearing prevention setting should still remain applied. I have: Plasma 5.4.2, KF 5.15, Qt 5.5.1 Intel graphics
Please attach the output of "qdbus org.kde.KWin /KWin supportInformation" before and after attaching the second screen (and ideally the output of "xrandr -q" as well)
Created attachment 95282 [details] KWin supportInformation - before
Created attachment 95283 [details] KWin supportInformation - after After attaching another monitor
Created attachment 95284 [details] xrandr -q (before)
Created attachment 95285 [details] xrandr -q (after)
The external screen becomes the new primary screen - as result you can expect tearing on the internal (but not on the external) screen. Suspending and resuming the compositor (SHIFT+Alt+F12) should be sufficient to clear the stage? Can you compile and try patches (I suspect the re-layout causes kscreen to remove all screens temporarily and that causes the driver to set the swapinterval to 0, ie. turn vsync off, since -for a brief moment- there's nothing to sync to)
I am experiencing the tearing on both screens regardless which of them became the primary one (also tested with the internal keeping the primary status). Yes, suspending and resuming the compositor (alt+shift+f12) is helpful - it bring the vsync on again. I think I can compile and try patches. Does it mean just cloning git://anongit.kde.org/kwin.git repo, resolve some deps, patch, build and run this custom kwin_x11 --replace? Or do I have to do the full blown ./kdesrc-build described in https://community.kde.org/Frameworks/Building ? Well, either way, I'll try :)
> Does it mean just cloning git://anongit.kde.org/kwin.git repo, resolve some deps, patch, build and run this custom kwin_x11 --replace? Yes. This is *not* a patch, it's just a very basic test on whether my assumption holds: diff --git a/glxbackend.cpp b/glxbackend.cpp index 924b010..60f9e79 100644 --- a/glxbackend.cpp +++ b/glxbackend.cpp @@ -692,6 +692,7 @@ void GlxBackend::screenGeometryChanged(const QSize &size) makeCurrent(); glViewport(0, 0, size.width(), size.height()); + setSwapInterval(1); // The back buffer contents are now undefined m_bufferAge = 0; This will unconditionally enable vsync on screen changes - for the GLX backend. If it doesn't work as expected, try diff --git a/glxbackend.cpp b/glxbackend.cpp index 924b010..60f9e79 100644 --- a/glxbackend.cpp +++ b/glxbackend.cpp @@ -692,6 +692,7 @@ void GlxBackend::screenGeometryChanged(const QSize &size) makeCurrent(); glViewport(0, 0, size.width(), size.height()); + setSwapInterval(0); + setSwapInterval(1); // The back buffer contents are now undefined m_bufferAge = 0;
PS: ensure to enable KDE_INSTALL_USE_QT_SYS_PATHS in cmake
Thanks. I did run the cmake with KDE_INSTALL_USE_QT_SYS_PATHS=ON. Successfully built kwin... I tried both proposed changes. Then also with some logging to ensure it is actually doing the setSwapInterval(1) method like this: makeCurrent(); glViewport(0, 0, size.width(), size.height()); qDebug() << "custom-kwin: setting swapInterval to 0"; setSwapInterval(0); qDebug() << "custom-kwin: setting swapInterval to 1"; setSwapInterval(1); qDebug() << "custom-kwin: setting swapInterval to DONE"; It did log these when I connected/disconnected motitor but unfortunately I can still see the tearing after that until kwin is restarted.
Sounds like a driver bug, we can't do much but asking it to pretty-please sync (but destroy and create a new GL context) glxbackend.cpp disables swapping around line 237, if that code isn't for some strange reason executed after GlxBackend::screenGeometryChanged.... one more thing (wild guess): instead of setSwapInterval(.); directly, try QTimer::singleShot(1000, [this]() { setSwapInterval(0); setSwapInterval(1); } );
The last one did not work either. Thanks a lot for your effort and time! You are answering really fast! Now I tried with EGL which is working as expected. On intel it has another issues but vsync is OK. Tomorrow I'll try with GLX on box with Radeon and report back.
So, the notebook with Radeon card doesn't have a visible tearing problem even if I set up vsync to "Never". Anyway should I report this issue to mesa or something? Or do you think it is not worth to repair it since GLX will eventually be replaced with repaired EGL?
If the bug is (as it seems) in the driver, it should be known and fixed since a) GLX will stay around for a while b) it may be some "optimization" that's eventually picked up by the EGL implementation as well Since it seems restricted to intel, it may depend on the acceleration. Try to downgrade: glamor -> sna -> uxa The current acceleration can be found in /var/log/Xorg.0.log https://wiki.archlinux.org/index.php/Intel_graphics#SNA_issues https://wiki.archlinux.org/index.php/Intel_graphics#Configuration
Thanks for these directions. I did some tests with interesting results - so about the lost vsync (OK - vsync preserved, NOK means vsync was lost): UXA & DRI2 - OK SNA & DRI2 (intel's default) - NOK glamor & DRI2 - NOK UXA & DRI3 - OK SNA & DRI3 - OK glamor & DRI3 - OK It seems enabling DRI3 solved a lot of issues. Aside from the loosing vsync one it looks like panel is not flickering anymore (it sometimes flicker quite a lot) and if one uses EGL, it started also working without previous issues.
Many thanks for sharing the information.