Skip to content

Solitary clients with single subsurface & verbose solitary/tearing/DS checks#11228

Merged
vaxerski merged 27 commits into
hyprwm:mainfrom
UjinT34:subsurface-fixes
Aug 22, 2025
Merged

Solitary clients with single subsurface & verbose solitary/tearing/DS checks#11228
vaxerski merged 27 commits into
hyprwm:mainfrom
UjinT34:subsurface-fixes

Conversation

@UjinT34

@UjinT34 UjinT34 commented Jul 26, 2025

Copy link
Copy Markdown
Contributor

Describe your PR, what does it fix/add?

Moved solitary/tearing/DS checks to CMonitor.
Added enums to describe possible blocking reasons for those features.
Added solitaryBlockedBy, tearingBlockedBy and directScanoutBlockedBy fields to hyprctl monitors.
Allowed clients with single opaque full-sized subsurface to be recognized as solitary clients.

Should help with debugging DS and tearing activation issues and fix some issues with wine-wayland.

Is there anything you want to mention? (unchecked code, possible bugs, found problems, breaking compatibility, etc.)

Partially fixes #10452. DS activation on my system goes up to this point:

[TRACE] [AQ] drm: Using drmModeAddFB2WithModifiers to import buffer into KMS: Size [Vector2D: x: 5120, y: 1440] with format XB24 and mod 216172782128496660
[ERR] [AQ] drm: Failed to submit a buffer with drmModeAddFB2WithModifiers
[ERR] [AQ] drm: Failed to submit a buffer to KMS

Maybe some DS step isn't updated with this new solitary logic or it can be an nvidia bug or some format negotiation ussue. Needs more testing with different apps and hw.

Tearing may report as blocked by next frame not being torn while tearing is active and working because the relevant flag is constantly flipped between frames. Probably should remove this value from the output.

DS and tearing checks should keep the current logic. Some of this logic is known to be incorrect, duplicated or might miss some edge cases. This PR will mess with fixes from #10020

Doesn't seem to break anything that was working with DS/tearing. Known to break some apps that couldn't activate DS/tearing without this PR. These features should be turned off manually for such apps and it should be investigated in a separate issue.

Is it ready for merging, or does it need work?

Ready

@fxzzi

fxzzi commented Jul 27, 2025

Copy link
Copy Markdown
Contributor

hyprlandCrashReport1261.txt
hyprlandCrashReport1681.txt

randomly crashing when opening and closing foot windows

tested it anyway, seems tearing is unable to trigger citing "next frame is not torn" in all instances I've seen. Ghost of Tsushima running in wine wayland shown below:

Screenshot from 25 07 27 10:58:01 Screenshot from 25 07 27 10:58:08

Then I tested with CEMU, playing The Legend of Zelda: the Windwaker HD (pretty sure this is fullscreen subsurface)
Tearing was unable to trigger here when I was focused on the game, moving focus to my secondary monitor froze the game, and then tearing went to true (still blocked by "next frame is not torn")

Moving focus back to the game, the game wouldn't recover from being frozen, switching workspace on that monitor to another and back to the game made it continue, with tearing now disabled:

Screenshot from 25 07 27 10:59:19 Screenshot from 25 07 27 11:00:08

@UjinT34

UjinT34 commented Jul 27, 2025

Copy link
Copy Markdown
Contributor Author

activelyTearing: true means that it's active. "next frame is not torn" flag is flipped between frames and hyprctl doesn't catch it in active state, ignore this "blocker" for now. Probably will remove it from output later.

Both crash reports point to CPopup::breadthfirst called by CWindow::popupsCount which wasn't modified. The only difference is that CWindow::popupsCount can be called by hyprctl monitors now and probably hits some popups during destruction. n is a WP inside CPopup::bfHelper and it isn't checked before accessing n->m_children

@fxzzi

fxzzi commented Jul 27, 2025

Copy link
Copy Markdown
Contributor

hmm, the foot clients I opened were empty actually, I didn't have hyprctl monitors running in them, they were just in shell.

Tearing is working on wine-wayland now afaict, disabled VRR on my monitor and could notice tearing in some instances.

However not working on CEMU still with the aforementioned issue of it only triggering when not focussed on it for some reason

@UjinT34

UjinT34 commented Jul 27, 2025

Copy link
Copy Markdown
Contributor Author

Does it randomly crash or always on close?
Always crashes on close for me. And in a strange way:

        # | ./build/Hyprland(_Z12getBacktracev+0x62) [0x563245d1d785]
                getBacktrace()
                /home/ujin/projects/Hyprland/src/helpers/MiscFunctions.cpp:746 (discriminator 2)
        #1 | ./build/Hyprland(_ZN14NCrashReporter18createAndSaveCrashEi+0x869) [0x563245ba3cef]
                NCrashReporter::createAndSaveCrash(int)
                /home/ujin/projects/Hyprland/src/debug/CrashReporter.cpp:200
        #2 | ./build/Hyprland(+0x902fed) [0x563245a78fed]
                handleUnrecoverableSignal(int)
                /home/ujin/projects/Hyprland/src/Compositor.cpp:113
        #3 | /usr/lib64/libc.so.6(+0x43b30) [0x7f35dca43b30]
                ??
                ??:0
        #4 | ./build/Hyprland(_ZNK9Hyprutils6Memory12CWeakPointerI6CPopupE7expiredEv+0x14) [0x563245c2c9ba]
                Hyprutils::Memory::CWeakPointer<CPopup>::expired() const
                /usr/include/hyprutils/memory/WeakPtr.hpp:116
        #5 | ./build/Hyprland(_ZN6CPopup12breadthfirstESt8functionIFvN9Hyprutils6Memory12CWeakPointerIS_EEPvEES5_+0x38) [0x563245c1fcaa]
                CPopup::breadthfirst(std::function<void (Hyprutils::Memory::CWeakPointer<CPopup>, void*)>, void*)
                /home/ujin/projects/Hyprland/src/desktop/Popup.cpp:348 (discriminator 1)
        #6 | ./build/Hyprland(_ZN7CWindow11popupsCountEv+0x78) [0x563245c5f67c]
                CWindow::popupsCount()
                /home/ujin/projects/Hyprland/src/desktop/Window.cpp:1325 (discriminator 6)

screenshot-1753614952

@fxzzi

fxzzi commented Jul 27, 2025

Copy link
Copy Markdown
Contributor

only quitting yea

@UjinT34

UjinT34 commented Jul 27, 2025

Copy link
Copy Markdown
Contributor Author

Should be fixed now. Happened when opaque was called on an unmapped window.

@vaxerski vaxerski left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also I'd love a few tests for these.

Comment thread src/debug/HyprCtl.cpp Outdated
Comment thread src/desktop/Popup.cpp Outdated
Comment thread src/desktop/Window.cpp
Comment thread src/helpers/Monitor.cpp Outdated
Comment thread src/helpers/Monitor.cpp Outdated
Comment thread src/helpers/Monitor.cpp
@fxzzi

fxzzi commented Jul 27, 2025

Copy link
Copy Markdown
Contributor

Should be fixed now. Happened when opaque was called on an unmapped window.

yep fixed.

more info on the cemu issue, it seems like the tearingBlockedBy is null when the window is frozen if that helps

Screenshot from 25 07 27 17:53:24

if you want to test cemu for free i've provided a basic homebrew pong app which you can run in the emulator without needing any firmware or official games. this can be used to reproduce the issue on your side (run the .elf file in cemu)
pong.zip

the fps is unlocked here but still repro'd the issue for me

EDIT: whilst the window is frozen if i move my mouse it unfreezes. freezes again when cursor is still

@UjinT34

UjinT34 commented Jul 27, 2025

Copy link
Copy Markdown
Contributor Author

This PR doesn't fix DS/tearing in general. Only makes single subsurface case acceptable for the DS/tearing code. And makes it easier to debug. So it'll be obvious when DS/tearing doesn't work due to config settings ("user settings", "window settings"), due to some other intentional internal check or due to something being broken (blocked by "null"). Internal checks and broken stuff are being fixed in #10020
If cemu doesn't freeze with this PR when tearing is disabled then I'd leave it as is since tearing doesn't work for cemu either way. Try cursor:no_hardware_cursors = 1, #10020 disables them when tearing is active.

@ikalco

ikalco commented Jul 28, 2025

Copy link
Copy Markdown
Contributor

hey if you want to you can cherry pick this commit from my old pr #10020,
It seems relevant to this pr and I don't really feel like rebasing mine for the millionth time

@UjinT34

UjinT34 commented Jul 28, 2025

Copy link
Copy Markdown
Contributor Author

hey if you want to you can cherry pick this commit from my old pr #10020, It seems relevant to this pr and I don't really feel like rebasing mine for the millionth time

that single commit doesn't seem to be enough. and there a lot of changes overall. better to cherry pick/merge/rebase in a separate PR after this one is merged

@LionHeartP

Copy link
Copy Markdown
Contributor

I tried this PR and Hyprland crashes for me 1-2 seconds in.
hyprlandCrashReport512.txt

@UjinT34

UjinT34 commented Jul 29, 2025

Copy link
Copy Markdown
Contributor Author

I tried this PR and Hyprland crashes for me 1-2 seconds in. hyprlandCrashReport512.txt

fixed

@vaxerski vaxerski left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generally lgtm just tests would be nice

@LionHeartP

Copy link
Copy Markdown
Contributor

I have been testing games with wine-wayland + HDR.
Tearing works now!
Direct Scanout works now! (There's a noticeable decrease in latency when moving the mouse)

Issue is if you have both enabled.

hyprctl monitors wil list Direct Scanout as blocked by tearing which is correct, BUT, the game will be frozen on one random frame. Sometimes it will render a few every few seconds and then stop, sometimes it'll just be a black screen.

Turning either one off, makes the other one work flawlessly.

Bonus fix (I'm not 100% sure it worked before), VRR works flawlessly with the wine-wayland + HDR combo. In the past, it'll work for a bit (like until the main menu of the game I can see the refresh rate adjusting), but when in-game, it would actually be stuck at max refresh rate. VRR worked fine on Xwayland btw, it was only on wine-wayland where this issue existed.

@UjinT34

UjinT34 commented Jul 30, 2025

Copy link
Copy Markdown
Contributor Author

generally lgtm just tests would be nice

any docs on how to write and run tests?

@vaxerski

vaxerski commented Aug 1, 2025

Copy link
Copy Markdown
Member

@UjinT34

UjinT34 commented Aug 1, 2025

Copy link
Copy Markdown
Contributor Author

Some tests might be broken. Couldn't verify them because for some reason I get

Monitor HEADLESS-2 (ID 1):
        0x0@60.00000 at 0x0
        ...
        active workspace: -1337 (snap)
        special workspace: 0 ()
        reserved: 0 0 0 0
        scale: 1.00
        transform: 0
        ...
        availableModes: 1920x1080@0.06Hz 

Should be ok with the correct monitor setup.
Is it possible to add tearing support to a headless output?

@vaxerski

vaxerski commented Aug 3, 2025

Copy link
Copy Markdown
Member

maybe its the snap test not coming back to workspace 1?

@UjinT34

UjinT34 commented Aug 4, 2025

Copy link
Copy Markdown
Contributor Author

Fixed most of the issues. Hard to make a sensible test without some hw features for headless outputs.

@LionHeartP

LionHeartP commented Aug 5, 2025

Copy link
Copy Markdown
Contributor

The only issue I have with this PR still is that tearing + DS makes it stop rendering, even though DS is deactivated according to hyprctl monitors due to tearing. If I disable DS, tearing works and vice versa.

Also is there a reason tearing should be preferred over DS? Shouldn't DS take precedence?

edit: Also, with just tearing enabled and not DS, it's bit wonky. It will freeze on a frame until I toggle fullscreen a few times.

ALL THESE TESTS ARE DONE WITH wine-wayland and HDR.

@UjinT34

UjinT34 commented Aug 5, 2025

Copy link
Copy Markdown
Contributor Author

The activation logic should be the same as on main. So the same issues should be present on main for apps that don't need this subsurface fix.
No particular reason to prefer tearing, it's the same on main. DS is usually a global setting and tearing is per-app through immediate rule, makes sense to prefer tearing when it's explicitly requested for an app.
Those issues and interaction between tearing and DS will be fixed after this PR.

HDR should produce more reliable results. CM for SDR DS doesn't exist atm and some SDR formats can't be used with DS at all.

This PR was meant to fix DS in wine-wayland on my nvidia setup and I am not interested in tearing. Ironically tearing seems to be working on every setup and DS works on mesa drivers. Might also work with some other videocard and nvidia driver version combos. No luck for me

@vaxerski

Copy link
Copy Markdown
Member

is this ready or...?

@UjinT34

UjinT34 commented Aug 20, 2025

Copy link
Copy Markdown
Contributor Author

Ready

@vaxerski vaxerski merged commit 0d45b27 into hyprwm:main Aug 22, 2025
13 checks passed
Boom-Hacker pushed a commit to Boom-Hacker/Hyprland that referenced this pull request Sep 27, 2025
…tearing/DS checks (hyprwm#11228)

Adds more verbose checks for various conditional rendering mechanisms
Boom-Hacker pushed a commit to Boom-Hacker/Hyprland that referenced this pull request Sep 27, 2025
…tearing/DS checks (hyprwm#11228)

Adds more verbose checks for various conditional rendering mechanisms
crthpl pushed a commit to crthpl/Hyprland that referenced this pull request Jun 3, 2026
…tearing/DS checks (hyprwm#11228)

Adds more verbose checks for various conditional rendering mechanisms
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow tearing / scanout with subsurface-based renderers

7 participants