gergo-salyi / multibg-sway

Set a different wallpaper for the background of each Sway workspace
Apache License 2.0
29 stars 1 forks source link

In some cases the rendering of wallpapers on workspace switching is slow and broken up to multiple frames #10

Open gergo-salyi opened 1 week ago

gergo-salyi commented 1 week ago
          **> If you have a different issue please tell me how to reproduce that one because I don't get so far what the issue that you're describing is.**

This appears to be the case. I cannot reproduce the issue anymore.

However, I remember that previously, my wallpaper only started to spawn after the workspace had been switched. As effect, I could notice a delay with of at least 250ms. I could see the following - when it happened:

1) Wallpaper on (workspace 1) was shown 2) Switch to workspace 2 3) The wallpaper of the previous workspace is flushed and the current workspace 1 appears black 4) Workspace 2 is shown in i3blocks 5) Workspace 2 does not show a Wallpaper yet 6) Wallpaper is being drawn but it is not ready yet. There are gaps noticeably around the edges, and we can see a rectangle already forming 7) Now the new Wallpaper is finished drawing

Switching back to workspace one, and the same behavior can be made out.

Originally posted by @zDEFz in https://github.com/gergo-salyi/multibg-sway/issues/7#issuecomment-2408633564

gergo-salyi commented 1 week ago

@zDEFz I only have guesses for this. multibg-sway does not have its own GPU context. It loads all the wallpapers on startup to wl_shm buffers which I think is GPU accessible host memory from sway's GPU context and is allocated through the wl_shm Wayland protocol.

Wallpaper is being drawn but it is not ready yet. There are gaps noticeably around the edges, and we can see a rectangle already forming [for at least 250ms (?)]

I would really appreciate a phone camera recording of this.

A partially drawn wallpaper should never happen due to a multibg-sway bug, becasue we don't "draw" the wallpaper through texture copying - we only do a buffer swap with already ready full-screen sized wallpapers. I can make some bad guesses:

I have one suggestion for now, please try starting multibg-sway with:

$ multibg-sway --pixelformat=baseline ~/my_wallpapers

(This forces our wl_shm to use format xrgb8888 instead of preferably using bgr888 which has bigger chances to be bugged)

Please see if this helps.

zDEFz commented 1 week ago

@zDEFz I only have guesses for this. multibg-sway does not have its own GPU context. It loads all the wallpapers on startup to wl_shm buffers which I think is GPU accessible host memory from sway's GPU context and is allocated through the wl_shm Wayland protocol.

Wallpaper is being drawn but it is not ready yet. There are gaps noticeably around the edges, and we can see a rectangle already forming [for at least 250ms (?)]

I would really appreciate a phone camera recording of this.

A partially drawn wallpaper should never happen due to a multibg-sway bug, becasue we don't "draw" the wallpaper through texture copying - we only do a buffer swap with already ready full-screen sized wallpapers. I can make some bad guesses:

* you multi-monitor lots-of-workspaces folks we have so many large wl_shm buffers that is the GPU driver spills some of it to slow-to-GPU-access memory

* the workspace change somehow loads your GPU so heavy that sway is late rendering the the new wallpaper

* we bring up some bug in sway, wlroots or the GPU driver

I have one suggestion for now, please try starting multibg-sway with:

$ multibg-sway --pixelformat=baseline ~/my_wallpapers

(This forces our wl_shm to use format xrgb8888 instead of preferably using bgr888 which has bigger chances to be bugged)

Please see if this helps.

It is unfortunate I cannot share the recording. Here is however what I can share:

Affected at 1080x1920 screen:

 Image
Format                                   : JPEG
Width                                    : 1 119 pixels
Height                                   : 2 652 pixels
Color space                              : YUV
Chroma subsampling                       : 4:2:0
Bit depth                                : 8 bits
Compression mode                         : Lossy
Stream size                              : 230 KiB (100%)

I did reproduce it again.

Behavior - exact

When using multibg-sway --pixelformat=baseline ~/.config/sway/wallpaper with specific images, the initial load is not steady. The image gets visibly sized once before it is loaded onto the first workspace. When switching from workspace 1 to 2, then the following happens on a tiled setup:

  1. Starting with 4 tiled windows and alacritty being half transparent - I can see part of the background wallpaper already
  2. Current Wallpaper gets fullscreened on the current workspace and all other windows disappear
  3. Workspace is switched
  4. Next Wallpaper appears

That is only the case with some images. I don't yet know what it is about the image that causes this. As soon as I have other wallpaper that causing this, I might be able to do a recording.

It is absolutely blazingly fast with most images. Maybe it is the rescaling??? But that's really what puts me off here. In any case, this creates this awkward effect where you are 1 frame off because the image shows in fullscreen in-between the switches when it isn't supposed to.

Edit the reason I don't want to share recording because I first need to find SFW image that has the same issue

gergo-salyi commented 6 days ago

Edit the reason I don't want to share recording because I first need to find SFW image that has the same issue [...] The image gets visibly sized [...]

I need to see that, I really don't have any idea what can cause that. You can email it to me I really don't mind (I'm trying to play a certain visual novel today between answering here and I bet the images I'm seeing there are worse then what you could ever send me :D ) Email here: https://github.com/gergo-salyi/multibg-sway/blob/2c9193129a642ed632f22d4732e858bb8445d07b/Cargo.toml#L4

It is absolutely blazingly fast with most images.

We convert all images to RGB 888 at startup right after opening them. It should never matter what format the image was initially.

Maybe it is the rescaling???

Rescaling is also done at startup (after converting to RGB 888). We don't show any wallpapers before it is all done. You will see sway's default grey background before our startup is fully completed.

If you want to send logs, then please launch with

RUST_LOG=trace multibg-sway ~/my_wallpapers

or

RUST_LOG=trace multibg-sway --pixelformat=baseline ~/my_wallpapers

And post the emitted log here from your terminal. And please tell me witch line of the log corresponds to the broken workspace / wallpaper switch.

Btw what GPU and driver are you using?

zDEFz commented 6 days ago

Btw what GPU and driver are you using?

AMD 6950XT Driver... aur/mesa-git 24.3.0_devel.194818.d3429a7e00d.d41d8cd-1 [+182 ~0.95] [Installed: 24.3.0_devel.195383.1b4e100779a.d41d8cd-1]

Because upstream mesa had culling issues, where textures started to miss in openGL context, except for Vulkan!

Alright, I prep the picture + video for you and send via mail.

Edit @gergo-salyi ... you should have received it

gergo-salyi commented 6 days ago

Got it. Is real time recording or slow mo?

zDEFz commented 6 days ago

Got it. Is real time recording or slow mo?

It's slo-mo. Look at the clock in bottom right. It's running :) It's at 240 FPS, that means its ~8 times slower than real time.

Real time was 00:06.04s but Video is 33s. Well, it almost mathing Oh, I see. Playback is at 30FPS (12%) speed

My screen refresh rate was also at 240Hz

Maybe 1 frame was 33ms? I can also set it to realtime if you want that file in realtime

gergo-salyi commented 6 days ago

So this soco70f.mov recording of yours, if you open it up in mpv and left click on the timestamp (left of the bottom progress bar) then mpv shows you millisecond timestamps. Using those, around 16s:

This is a 4 frame at 240 FPS = 16 ms delay.

Wallpaper is being drawn but it is not ready yet

I have bad news for you, I think the fading is just your monitor's pixel response time, there is no drawing there. Your monitor has 1-2 frames at 240 FPS of pixel response time based on your recording.

I think this is just issue 7, only that it is worse then I though in regards that it is not just 1 frame at any frame rate but truly a 10 ms+ delay at whatever frame rate (meaning 3-4 frames at 240 FPS).

But you said:

delay with of at least 250ms

Where is it? I cannot see such delay.

gergo-salyi commented 6 days ago

I tried your script (bit changed for my setup):

#!/bin/bash
set -exo pipefail

mpvpaper -f -o "--no-config --input-ipc-server=/tmp/mpv-sock" -n 10 'HDMI-A-1' /home/gergo/image/wallpaper/HDMI-A-1/1.png &

# Function to load the wallpaper based on the workspace number
load_wallpaper() {
    workspace_num=$1
    echo "loadfile /home/gergo/image/wallpaper/HDMI-A-1/$workspace_num.png" | socat - /tmp/mpv-sock
}

while true; do
    # Subscribe to workspace change events
    swaymsg -t subscribe '["workspace"]' | while read -r event; do
        # Get the current workspace number
        workspace_num=$(swaymsg -t get_workspaces | jq '.[] | select(.focused == true).num')

        # Load the appropriate wallpaper
        load_wallpaper $workspace_num
    done
done

Nice work, but it is really difficult for me to believe that this has less delay then multibg-sway. It does almost exactle the same thing as multibg-sway, but it has 3 extra execve (swaymsg, jq, socat) and a full png decompression at every wallpaper change.

EDIT: As I tried it and for me with an Intel iGPU at 60 FPS multibg-sway has max 1 frames of delay, and with your script I see visible more delay so 2 or more frames I guess. But this is just my test on my system.

If you feel the energy for it, slow-mo your script as well, I gonna have to rethink everything I know about this problem if it somehow turns out to be better :)

gergo-salyi commented 6 days ago

Anyways I'm gonna work on issue 7 in the next 1-2 weeks and I think there is hope that it will solve your complaint with the current delay that multibg-sway has. (But I'm off for today, thank you for your patience and help so far)

zDEFz commented 6 days ago

I have bad news for you, I think the fading is just your monitor's pixel response time, there is no drawing there. Your monitor has 1-2 frames at 240 FPS of pixel response time based on your recording.

But the issue is only with these pictures? Are you really sure its my display? https://www.rtings.com/monitor/reviews/benq/zowie-xl2546k

This is a 4 frame at 240 FPS = 16 ms delay.

Total Response Time 7.6 ms

If you feel the energy for it, slow-mo your script as well, I gonna have to rethink everything I know about this problem if it somehow turns out to be better :)

Well. As I remember it, it does not have the issue with the image. Let me do that later this day and record it.

gergo-salyi commented 6 days ago

Total Response Time 7.6 ms

Yes, that is what we are seeing on the recording. And 7.6 ms is an average. See your

https://www.rtings.com/monitor/reviews/benq/zowie-xl2546k

Scroll to "Response Time @ Max Refresh Rate", it will show that the worst value is transitioning from 0% pixel brightness to 80% pixel brightness takes 13.4 ms.

At 240 FPS 1 frame is 4.17 ms, so it takes (13.4 ms / 4.17 ms = ) 3.21 frames until putting a bright image part in place of a dark image part can be viewed perfectly clearly on the monitor. This is just normal monitor things, there is no GPU activity there.

(In the future in the context of programming please only use the word "drawing" for software or GPU activities that change the content of the framebuffer. The monitor's pixels responding to a static framebuffer is not "drawing". This will be clear on a OBS recording if you would ever make one.)

gergo-salyi commented 6 days ago

Btw only as a sanity check can you please post here your output of

$ swaymsg -t get_outputs

You can censor serial number if it would contain any

zDEFz commented 6 days ago

Btw only as a sanity check can you please post here your output of

$ swaymsg -t get_outputs

You can censor serial number if it would contain any

I just added a new display today. Ignore the LG Display for testing purposes.

https://0x0.st/X6yt.json

gergo-salyi commented 6 days ago

Both your BNQ ZOWIE XL LCD monitors shows that current_mode has a refresh rate of 143.981 Hz and not 240 Hz.

zDEFz commented 6 days ago

Both your BNQ ZOWIE XL LCD monitors shows that current_mode has a refresh rate of 143.981 Hz and not 240 Hz.

Correct. I switch it when I need it at 240 to 240. Thats due to memclock reasons, saving 70 Watt The recording was done when they were at 240Hz.

Like so

 % which 144hz
144hz: aliased to if [[ $(xrandr | grep "\*" | awk "{print int(\$2+0.5)}" | tail -n 1) != 144 ]]; then swaymsg "output * mode 1920x1080@144Hz"; fi

% which 240hz
240hz: aliased to if [[ $(xrandr | grep "\*" | awk "{print int(\$2+0.5)}" | tail -n 1) != 240 ]]; then swaymsg "output * mode 1920x1080@240Hz"; fi
zDEFz commented 4 days ago

By the way, I am claiming that this effect is non-present with the script I've built. Whether its slower or faster, the apparent sizing behavior does not happen there. I think maybe we can try couple different things for displaying? Or just waiting for the other thing to be taken on.

It's really not a fading issue. It's that the image appears to be 'mazimixed' on the same workspace while the other windows disappear before switching to the next. And thats only happening with some images.