sway
sway copied to clipboard
Add support for tearing-control-v1
References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3871
Adds option to allow tearing per output, as well as an option to force enable or disable tearing for a specific application using a window rule. Only works with fullscreen applications.
this is no longer blocked by the wlroots MR, would love to see this finished and merged
Marked as ready for review. Works on my end (i see tearing) when setting tearing allowed on the output and an override per view, with WLR_DRM_NO_ATOMIC=1
. Not tested using Mesa git and automatically setting the hint though.
I don't know if my approach is correct, since my knowledge about (Wayland) compositors is limited, so if anything can be improved let me know.
After playing for some time it can cause few seconds long freezes when switching between workspaces, closing some apps, trying to type something into thunar. Tho there are times when it's fine, I didn't find a consistent way of reproducing this. Temporary solution I've found is switching to a different TTY and back. But usually the issues comes back quite quickly. dmesg doesn't say anything. Potentially worth noting is that I'm also using VRR, I didn't try to use this MR without VRR. I've also seen this on hyprland but I don't have anything to prove it's wlroots' fault.
I've been using the initial PR since may and everything has been working as expected! :)
One thing, I'd like to see (and I'm not sure, this may be more related to wlroots) is tearing on the mouse cursor. My reasoning is:
- Actually seeing the tearing on such a tiny object is pretty unlikely (24 / 1080 = ~every 45th frame)
- It is one area, where it makes the largest perceivable difference
Seeing this as an option would be awesome!
I don't see how cursor tearing would actually be useful. Can't think of any case where minimizing latency on the cursor image would be useful. (Note, tearing on cursor would only apply to the cursor image, not the cursor position.)
I don't see how cursor tearing would actually be useful. Can't think of any case where minimizing latency on the cursor image would be useful. (Note, tearing on cursor would only apply to the cursor image, not the cursor position.)
Okay I thought it would make it possible to render the cursor earlier. If it does not affect the cursor position then it makes no sense.
I guess I will wait for the new frame scheduler to be merged and see if that improves things.
Specifically on 60Hz the cursor feels noticeably delayed currently and I thought this might help because the latency improvement in games is VERY apparent.
I've set:
for_window [title=".*"] tearing_allowed yes
output DP-1 { tearing_allowed 1 }
Is that enough to enable tearing with this patch (and unstable wlroots git)? I still see New presentation hint 0 received for surface
. Anyone know of a good way to test if this is working?
EDIT: Yes, it seems to work. I can now see tearing in a fullscreen vkcube
.
EDIT 2: It would be nice if a debug message could be printed when an application is allowed to tear. Other than that, so far so good.
EDIT 3: And a default_tearing_allowed
in place of for_window [title=".*"] tearing_allowed yes
would be nice too.
Not sure about the naming of the options, e.g. output allow_tearing
seems to actually be a way to force tearing on/off.
I'm not sure if you know this already but I don't think this builds against any wlroots commit anymore. I've tried e.g. b80337a8f2bb5d032f533ed5e0feb6292670528f
, ce89f49b7aab281198fad64e9a825a24dbf72e3d
, 1968ada2132237f5bf8e40b6bf903fbce76c0b40
and da5f53b46176f05731e94dec5f079c1ce7a57ed5
.
EDIT: This patch against Sway c5fd8c050f7ddbfe3e5b7abc8f5f6ace3a3c5307
does not build for (seemingly) any wlroots. An older version of this patch against Sway bff991dfdc63ca3785a810ff4d913ddfd71677a1
builds against Wlroots 0.17.1
EDIT2: This seems to work except for spam of [DEBUG] [wlr] [backend/drm/legacy.c:51] connector DP-1: Cannot change scan-out buffer parameters with legacy KMS API
in the log for a fullscreen alacritty.
EDIT3: I'm seeing some garbling of games however which is what convinced me to try to update today. I think it must be related to either Linux 6.7-rc8 or Mesa 23.3.1
EDIT4: Garblage appears to be resolved with Mesa 23.3.3
I'm not sure if you know this already but I don't think this builds against any wlroots commit anymore.
Fixed by rebase, builds with latest wlroots-git
Just gave it a go. It does build against current wlroots (4688a371e04787f5bb059e80b5de506f0a8f00ff
) and stuff works after switching to xwayland d7f1909e7c198607794da5f4d778ce53139ff851
. I no longer see the tearing I previously saw in vkcube
but this may have been a bug previously. A better way to test tearing would be nice. Also, I'll test the new non-legacy atomic tearing page flips at some point too.
EDIT: After testing with Smooth Frog, I don't see any tearing.
EDIT2: Tested the same application on X11 and I can see tearing. It seems like, for me, tearing is broken with the current state of this patch. Though, of course, it could be because of Wlroots changes underneath.
Testing with Linux 6.8-rc1 and libdrm 2.4.120 without setting WLR_DRM_NO_ATOMIC=1
, I don't see any tearing nor any debug messages suggesting that something is broken.
EDIT: Except what's below. I don't know it's alacritty
specific or not though.
00:00:07.711 [DEBUG] [wlr] [backend/drm/fb.c:172] Buffer format 0x34325241 with modifier 0x200000028A6BF04 cannot be scanned out
00:00:07.711 [DEBUG] [wlr] [backend/drm/drm.c:600] connector DP-1: Failed to import buffer for scan-out
00:00:07.711 [ERROR] [wlr] [backend/drm/atomic.c:74] connector DP-1: Atomic commit failed: Invalid argument
00:00:07.711 [DEBUG] [wlr] [backend/drm/atomic.c:78] (Atomic commit flags: PAGE_FLIP_EVENT | PAGE_FLIP_ASYNC | ATOMIC_NONBLOCK)
Tested the same application on X11 and I can see tearing. It seems like, for me, tearing is broken with the current state of this patch. Though, of course, it could be because of Wlroots changes underneath.
I see. I'll have to investigate this some more. Recently some massive changes were made to the codebase. I made the changes based on a general outline of it, but overall I'm not involved enough with Sway and wlroots to know every detail of it. I don't have any trouble implementing it, but i may need some help with the approach based on recent changes.
I've fixed this PR in my own fork in this commit: https://github.com/vimproved/sway/commit/49590198febe073528677c80f2b33ec74ead1c75. It seems like tearing_page_flip needs to be updated every frame, and putting it behind if (output->gamma_lut_changed || output->tearing_state_changed)
broke it. However, now it's calling wlr_output_commit_state twice every frame (once to apply tearing_page_flip, and once in wlr_scene_output_commit), which might be an issue (I'm not 100% sure).
@emersion could you comment on what changes need to be made to this patch (with or without @vimproved's changes) before it can be merged? As Linux 6.8 will probably be released soon with the atomic tearing page flips and Sway 1.9 has been released (so timing for new features is good), it seems like a good time to work on this. I'd be happy to help work on this if there are any concerns that you have.
any news on when this will be merged?
For those trying to use this MR with upstream and failing to see any tearing, there's a working version at https://github.com/vimproved/sway/tree/tearing_control (thanks vimproved for maintaining the MR and thanks RicArch97 for creating it!).
Test tearing with:
vkcube --present_mode 0
It should show very visible tearing.
Don't forget to fullscreen the window!
For those trying to use this MR with upstream and failing to see any tearing, there's a working version at https://github.com/vimproved/sway/tree/tearing_control (thanks vimproved for maintaining the MR and thanks RicArch97 for creating it!).
Test tearing with:
vkcube --present_mode 0
It should show very visible tearing.
Don't forget to fullscreen the window!
My latest changes already included the suggestion from @vimproved (thanks!). The difference is that i didn't rebase this branch in some time. Last time i tested it, the output commits were failing with the tearing flips enabled so i assumed the backend (wlroots, DRM) still needed work before the tearing flips could work correctly.
I definitely haven't forgotten about this MR, i just don't recommend using this yet until it's actually ready and reviewed. I just rebased it as well, and tested it with vkcube and overwatch 2. The commits no longer fail and the tearing works as expected (including using the hints provided by the application / game) without the need to launch with WLR_DRM_NO_ATOMIC=1
. So we seem to be moving in the right direction.
@RicArch97 I understand 100%, I choose to use experimental stuff all the time (you'd probably cringe at my heavily experimental and patched custom compiled OS bits...) but I can get why you don't quite recommend it yet before the proper code review, though I think you'd agree people who can patch and compile code from github know enough about what they're doing to not throw pitchforks at you if their compositor crashes 😂. Thank you for the official rebase of this MR and hope it gets reviewed and merged in the near future!
I'm sorry, but I'm pulling my hair out trying to get this to work.
output * allow_tearing yes
for_window [title=".*"] allow_tearing yes
Running an application that should tear just doesn't show tearing and resets the allow_tearing
flag in
sway apparently:
$ swaymsg -t get_outputs | rg allow_tearing
"allow_tearing": true,
"allow_tearing": true,
$ vkcube --present_mode 0
Selected GPU 0: AMD Radeon RX 6800 (RADV NAVI21), type: DiscreteGpu
$ swaymsg -t get_outputs | rg allow_tearing
"allow_tearing": false,
"allow_tearing": true,
swaymsg version 1.10-dev-203ac891 (Mar 18 2024, branch 'tearing_control')
To add to this: I'm on Kernel 6.9.5 and I'm definitely getting PRESENT_MODE_IMMEDIATE_KHR reported by Vulkan.
I also never got it to work in KDE ... so maybe its an issue with the kernel
Oops, it looks like i still had WLR_DRM_NO_ATOMIC=1
set in my dev shell. So for now it looks like it is still required to set this to make the tearing work....
Oops, it looks like i still had
WLR_DRM_NO_ATOMIC=1
set in my dev shell. So for now it looks like it is still required to set this to make the tearing work....
Yes, its working with WLR_DRM_NO_ATOMIC=1
, glad to here its nothing specific to my system I guess!
My latest changes already included the suggestion from @vimproved (thanks!).
No problem, thank you for making this PR in the first place! I use the live version of sway on gentoo with this patch so I've mainly just been rebasing it for personal use but I'm glad other people have found it useful. For now WLR_DRM_NO_ATOMIC=1
seems to still be required, I tried looking into why it wasn't working at some point but came up with inconclusive results.
I have a question, will there be an option to enable tearing for everything, so there's no need to manually add each and every app?
I have a question, will there be an option to enable tearing for everything, so there's no need to manually add each and every app?
I think this is already possible by just defining a window rule using some wildcards, e.g. everything that gets fullscreen should then be configured to tear, still learning the syntax here as well.
Wonder if there would be a global 'tear all fullscreen option' , if it could be toggled on the fly as well (binding keys etc.), not sure what is possible and what the limitations are, maybe it can only be set when getting to/from fullscreen.
I have a question, will there be an option to enable tearing for everything, so there's no need to manually add each and every app?
I think this is already possible by just defining a window rule using some wildcards, e.g. everything that gets fullscreen should then be configured to tear, still learning the syntax here as well.
Wonder if there would be a global 'tear all fullscreen option' , if it could be toggled on the fly as well (binding keys etc.), not sure what is possible and what the limitations are, maybe it can only be set when getting to/from fullscreen.
In this case will sway count as fullscreen? What I meant is no sync at all for everything including tiles, not just apps which went into fullscreen. Like a global toggle.
In this case will sway count as fullscreen? What I meant is no sync at all for everything including tiles, not just apps which went into fullscreen. Like a global toggle.
This should be the output option:
output * allow_tearing yes
if I read this correctly some posts back.
The idea of the tearing hints is that the application can inform the compositor that it wants to tear. For games that would be when VSync is disabled in the game. By default we react to the hints if allow_tearing
is set to true on the output.
The window rules allow_tearing
can be used if you want to force it for a specific app (maybe if the app doesn't provide a hint for async) or force disable it for an app to get the current mailbox present mode (VSync off in game, but no tearing allowed by compositor).