Bug 354749 - [intel] [sna] [glamor] [dri2] swapcontrol ineffective after randr events, new contexts ok
Summary: [intel] [sna] [glamor] [dri2] swapcontrol ineffective after randr events, new...
Status: RESOLVED UPSTREAM
Alias: None
Product: kwin
Classification: Plasma
Component: glx (show other bugs)
Version: 5.4.2
Platform: Arch Linux Linux
: NOR normal
Target Milestone: ---
Assignee: KWin default assignee
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-11-02 19:54 UTC by Martin Kostolný
Modified: 2015-11-08 07:38 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:
thomas.luebking: Intel+


Attachments
KWin supportInformation - before (5.55 KB, text/plain)
2015-11-03 06:57 UTC, Martin Kostolný
Details
KWin supportInformation - after (5.63 KB, text/plain)
2015-11-03 06:57 UTC, Martin Kostolný
Details
xrandr -q (before) (1.02 KB, text/plain)
2015-11-03 06:58 UTC, Martin Kostolný
Details
xrandr -q (after) (1.34 KB, text/plain)
2015-11-03 06:59 UTC, Martin Kostolný
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Kostolný 2015-11-02 19:54:20 UTC
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
Comment 1 Thomas Lübking 2015-11-02 20:16:43 UTC
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)
Comment 2 Martin Kostolný 2015-11-03 06:57:11 UTC
Created attachment 95282 [details]
KWin supportInformation - before
Comment 3 Martin Kostolný 2015-11-03 06:57:53 UTC
Created attachment 95283 [details]
KWin supportInformation - after

After attaching another monitor
Comment 4 Martin Kostolný 2015-11-03 06:58:48 UTC
Created attachment 95284 [details]
xrandr -q (before)
Comment 5 Martin Kostolný 2015-11-03 06:59:20 UTC
Created attachment 95285 [details]
xrandr -q (after)
Comment 6 Thomas Lübking 2015-11-03 16:25:25 UTC
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)
Comment 7 Martin Kostolný 2015-11-04 20:09:17 UTC
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 :)
Comment 8 Thomas Lübking 2015-11-04 21:30:55 UTC
> 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;
Comment 9 Thomas Lübking 2015-11-04 21:41:15 UTC
PS: ensure to enable KDE_INSTALL_USE_QT_SYS_PATHS in cmake
Comment 10 Martin Kostolný 2015-11-04 22:08:05 UTC
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.
Comment 11 Thomas Lübking 2015-11-04 22:53:36 UTC
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); } );
Comment 12 Martin Kostolný 2015-11-04 23:15:05 UTC
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.
Comment 13 Martin Kostolný 2015-11-05 15:30:58 UTC
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?
Comment 14 Thomas Lübking 2015-11-07 14:57:53 UTC
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
Comment 15 Martin Kostolný 2015-11-08 01:54:23 UTC
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.
Comment 16 Thomas Lübking 2015-11-08 07:38:32 UTC
Many thanks for sharing the information.