swaywm / sway

i3-compatible Wayland compositor
https://swaywm.org
MIT License
14.41k stars 1.1k forks source link

Window jitter when resizing #7195

Open ghost opened 1 year ago

ghost commented 1 year ago
zDEFz commented 1 year ago

What application do yo u even use for testing? I tried to reproduce on a 6950xt on a 240hz monitor. The footage is in 60fps cause I didnt know how to up it to 240 in OBS. However, the jitter you had in the bottom, I cannot see. Do you see it? https://transfer.sh/Sy7nlE/2022-10-03%2017-53-55.mkv

ghost commented 1 year ago

@zDEFz, for recording I use wf-recorder. On the proprietary NVIDIA driver the fps is unstable, but on nouveau (which is on the video) the fps is stable. As for your bug, I notice it in some applications, so you are not alone :)

zDEFz commented 1 year ago

Wait. I didnt notice the issue in the video I posted. Can you see the issue? I am on the amdgpu driver.

ghost commented 1 year ago

If you look closely, you can see that the borders sometimes do not correspond to the window. With me this bug is more evident (in mpv for example), probably because I have NVIDIA gpu P.S: Although idk, maybe that's how it's meant to be :)

ghost commented 1 year ago

I forgot to mention that there is no jitter when resizing from the bottom right corner.

Xyene commented 1 year ago

Could you try to see if the issue reproduces with https://github.com/swaywm/sway/pull/6844?

ghost commented 1 year ago

Thanks, but it didn't help :C (I compiled sway from this branch) In wayfire, by the way, there is no such problem.

Nefsen402 commented 1 year ago

Yep, I have known this problem for a very long time. Here's why it's happening:

  1. Sway configures the surface for a new size
  2. Sway configures a new surface size (because of dragging quickly)
  3. The application responds to the first configure by committing a buffer of the size of the first configure. Sway will now resize the floating container to the buffer size. For only floating windows and nothing else, sway will try to resize the container to whatever the client wishes. We need this feature because of mpv (mpv will try to preserve the aspect ratio of the content in a floating view)
  4. The application responds to the second configure resizing the surface once again causing perceived lagginess and imperfect frames.

I tried to fix this long ago but there are some pretty tricky edge cases. I will eventually fix this up for once and for good once I get around to rewriting the transaction system. The third of a planned trilogy of big rewrite PRs. (#6844 being the first)

oifj34f34f commented 1 year ago

As far as I can tell, the problem also appears in tinywl

zDEFz commented 1 year ago

Hijacking this really quick:

Hardware is 5800x3d + 6950 XT ( connected to 240Hz Monitors and a third 120Hz Monitor via DisplayPort). Sleep/DPMS/switching monitors is not used. However, at night, I shut the monitors physically off.

@Nefsen402 there are other issues, that arent addressed yet, too. I had to leave sway behind for crashing easily 5 times a day during Browsing in firefox / working in vscode. All I found in the logs was that amdgpu-reset was called, and that somehow sway crashed. It wasn't related to thermals either.

I made now an really big effort and it was also present in fedora+sway, similar to archlinux+sway. I switched to Fedora+GNOME and after much work on some third party extensions, I had a very similar result as to what sway can do with its many possible window rules. It is stable. And I no longer need to fiddle with this stuff.

As for sway crashing theres tons of crash reports and I really had a hard time to debug mine, there should be a guide for using gdb to debug sway (let gdb start sway) and getting logs. I was really lost when it just said check logs ( looked at journalctl and dmesg )... If we don't have proper logs, we may have a hard time addressing this other stuff.

https://github.com/swaywm/sway/issues?q=crash

There seems tons of issues already closed, however without fixing whatever issue I had.

Nefsen402 commented 1 year ago

Hijacking this really quick:

Hardware is 5800x3d + 6950 XT ( connected to 240Hz Monitors and a third 120Hz Monitor via DisplayPort). Sleep/DPMS/switching monitors is not used. However, at night, I shut the monitors physically off.

@Nefsen402 there are other issues, that arent addressed yet, too. I had to leave sway behind for crashing easily 5 times a day during Browsing in firefox / working in vscode. All I found in the logs was that amdgpu-reset was called, and that somehow sway crashed. It wasn't related to thermals either.

I made now an really big effort and it was also present in fedora+sway, similar to archlinux+sway. I switched to Fedora+GNOME and after much work on some third party extensions, I had a very similar result as to what sway can do with its many possible window rules. It is stable. And I no longer need to fiddle with this stuff.

As for sway crashing theres tons of crash reports and I really had a hard time to debug mine, there should be a guide for using gdb to debug sway (let gdb start sway) and getting logs. I was really lost when it just said check logs ( looked at journalctl and dmesg )... If we don't have proper logs, we may have a hard time addressing this other stuff.

https://github.com/swaywm/sway/issues?q=crash

There seems tons of issues already closed, however without fixing whatever issue I had.

Try using my scene patches for sway. !6844. They rewrite the rendering in sway which tends to crash when the gpu resets. If your gpu resets with the patches, sway won’t crash but it will look like it’s frozen. At least that would let you verify what’s happening. To fix the freezing there are Wlroots patches waiting that I can link you to. I will not respond immediately as I am traveling. Messaging you from on the Shinkansen!

zDEFz commented 1 year ago

Try using my scene patches for sway. !6844. They rewrite the rendering in sway which tends to crash when the gpu resets. If your gpu resets with the patches, sway won’t crash but it will look like it’s frozen. At least that would let you verify what’s happening. To fix the freezing there are Wlroots patches waiting that I can link you to. I will not respond immediately as I am traveling. Messaging you from on the Shinkansen!

@Nefsen402 Hope you have a nice time. Yea, some info would be helpful.

oifj34f34f commented 8 months ago

It's OP. The link to the demo doesn't seem to be working, so I've recorded a new one:

demo.webm

Edit: fixed broken video, thanks @zDEFz

zDEFz commented 8 months ago

It's OP. The link to the demo doesn't seem to be working, so I've recorded a new one: 1.mp4

your video doesnt play

raiguard commented 6 months ago

I am getting a very extreme version of this with our game:

https://github.com/swaywm/sway/assets/3515394/483f0ec7-9cc1-42f8-983d-d61b80538ff0

Wayland + SDL logging seems to indicate that it is as described by @Nefsen402 - the game commits a buffer with an outdated size which causes Sway to snap the window to that size, raising another event, and so on.

I originally suspected SDL to be at fault but I made a sample SDL application and it resizes perfectly well, and the game behaves perfectly well on Gnome.

EDIT: I believe that this is due to double-buffered vsync. The old buffer has an outdated size and when it is committed Sway resizes the window.

INFO: SDL EVENT: SDL_WINDOWEVENT (timestamp=10850 windowid=1 event=SDL_WINDOWEVENT_SIZE_CHANGED data1=1959 data2=752)
INFO: SDL EVENT: SDL_WINDOWEVENT (timestamp=10850 windowid=1 event=SDL_WINDOWEVENT_RESIZED data1=1959 data2=752)
[ 599142.884]  -> xdg_surface@30.ack_configure(13686)
[ 599158.853] wl_callback@43.done(76270220)
[ 599158.859]  -> wl_surface@32.frame(new id wl_callback@49)
[ 599158.911] wl_buffer@42.release()
[ 599158.915]  -> wl_buffer@42.destroy()
[ 599158.917] wl_callback@41.done(13685)
[ 599158.920]  -> zwp_linux_dmabuf_v1@31.create_params(new id zwp_linux_buffer_params_v1@41)
[ 599158.930]  -> zwp_linux_buffer_params_v1@41.add(fd 92, 0, 0, 8192, 33554432, 546749187)
[ 599158.934]  -> zwp_linux_buffer_params_v1@41.add(fd 93, 1, 6291456, 2048, 33554432, 546749187)
[ 599158.937]  -> zwp_linux_buffer_params_v1@41.create_immed(new id wl_buffer@43, 1959, 748, 875713112, 0)
[ 599158.939]  -> zwp_linux_buffer_params_v1@41.destroy()
[ 599158.941]  -> wl_surface@32.attach(wl_buffer@43, 0, 0)
[ 599158.943]  -> wl_surface@32.damage(0, 0, 2147483647, 2147483647)
[ 599158.945]  -> wl_surface@32.commit()
[ 599158.946]  -> wl_display@1.sync(new id wl_callback@44)
[ 599159.559] wl_display@1.delete_id(50)
[ 599159.564] wl_display@1.delete_id(42)
[ 599159.566] wl_display@1.delete_id(41)
[ 599159.568] wl_display@1.delete_id(35)
[ 599159.570] wl_display@1.delete_id(49)
[ 599159.572] wl_display@1.delete_id(44)
[ 599159.574] wl_callback@35.done(76270236)
[ 599159.577]  -> wl_surface@32.damage_buffer(0, 0, 1959, 752)
[ 599159.580]  -> wl_surface@32.frame(new id wl_callback@35)
[ 599159.583] xdg_toplevel@38.configure(1959, 762, array[8])
[ 599159.586] xdg_surface@30.configure(13687)
[ 599159.589]  -> wl_surface@32.set_buffer_scale(1)
[ 599159.591]  -> xdg_surface@30.set_window_geometry(0, 0, 1959, 762)
[ 599159.594]  -> wl_compositor@5.create_region(new id wl_region@41)
[ 599159.597]  -> wl_region@41.add(0, 0, 1959, 762)
[ 599159.601]  -> wl_surface@32.set_opaque_region(wl_region@41)
[ 599159.604]  -> wl_region@41.destroy()
INFO: SDL EVENT: SDL_WINDOWEVENT (timestamp=10867 windowid=1 event=SDL_WINDOWEVENT_SIZE_CHANGED data1=1959 data2=762)
INFO: SDL EVENT: SDL_WINDOWEVENT (timestamp=10867 windowid=1 event=SDL_WINDOWEVENT_RESIZED data1=1959 data2=762)
[ 599159.613]  -> xdg_surface@30.ack_configure(13687)
[ 599173.273] wl_display@1.delete_id(41)
[ 599173.299] xdg_toplevel@38.configure(1959, 762, array[4])
[ 599173.313] xdg_surface@30.configure(13688)
[ 599173.325]  -> xdg_surface@30.ack_configure(13688)
[ 599175.094] wl_callback@49.done(76270236)
[ 599175.100]  -> wl_surface@32.frame(new id wl_callback@41)
[ 599175.153] wl_callback@44.done(13687)
[ 599175.158]  -> zwp_linux_dmabuf_v1@31.create_params(new id zwp_linux_buffer_params_v1@44)
[ 599175.169]  -> zwp_linux_buffer_params_v1@44.add(fd 92, 0, 0, 8192, 33554432, 546749187)
[ 599175.173]  -> zwp_linux_buffer_params_v1@44.add(fd 93, 1, 6291456, 2048, 33554432, 546749187)
[ 599175.176]  -> zwp_linux_buffer_params_v1@44.create_immed(new id wl_buffer@49, 1959, 752, 875713112, 0)
[ 599175.178]  -> zwp_linux_buffer_params_v1@44.destroy()
[ 599175.180]  -> wl_surface@32.attach(wl_buffer@49, 0, 0)
[ 599175.182]  -> wl_surface@32.damage(0, 0, 2147483647, 2147483647)
[ 599175.184]  -> wl_surface@32.commit()
[ 599175.185]  -> wl_display@1.sync(new id wl_callback@42)
[ 599175.796] wl_display@1.delete_id(44)
[ 599175.800] wl_display@1.delete_id(35)
[ 599175.801] wl_display@1.delete_id(41)
[ 599175.802] wl_display@1.delete_id(42)
[ 599175.804] wl_callback@35.done(76270252)
[ 599175.805]  -> wl_surface@32.damage_buffer(0, 0, 1959, 762)
[ 599175.807]  -> wl_surface@32.frame(new id wl_callback@35)
[ 599175.809] xdg_toplevel@38.configure(1959, 752, array[4])
[ 599175.811] xdg_surface@30.configure(13689)
[ 599175.813]  -> wl_surface@32.set_buffer_scale(1)
[ 599175.815]  -> xdg_surface@30.set_window_geometry(0, 0, 1959, 752)
[ 599175.817]  -> wl_compositor@5.create_region(new id wl_region@44)
[ 599175.818]  -> wl_region@44.add(0, 0, 1959, 752)
[ 599175.820]  -> wl_surface@32.set_opaque_region(wl_region@44)
[ 599175.822]  -> wl_region@44.destroy()
INFO: SDL EVENT: SDL_WINDOWEVENT (timestamp=10883 windowid=1 event=SDL_WINDOWEVENT_SIZE_CHANGED data1=1959 data2=752)
INFO: SDL EVENT: SDL_WINDOWEVENT (timestamp=10883 windowid=1 event=SDL_WINDOWEVENT_RESIZED data1=1959 data2=752)
Nefsen402 commented 6 months ago

SDL should wait for last configure to complete before resizing again. This is what most applications do.

zDEFz commented 6 months ago

SDL should wait for last configure to complete before resizing again. This is what most applications do.

Apparently, in i3 this is not an issue. Since sway is i3-compatible, it should be implied that the same behavior applies. Is the assumption correct that it may be a Wayland Protocol implementation specific variance across different Wayland implementations? I am not aware that it is a consistent issue across Wayland implementations.

If you change the SDL behavior from Factorio's end instead of sways end, how can you be sure you don't do more harm than good?

bl4ckb0ne commented 6 months ago

Apparently, in i3 this is not an issue. Since sway is i3-compatible

The configuration is compatible, i3 and Sway are using 2 different window protocol (X11 and Wayland respectively).

Wayland defines a protocol that both server and client must respect. As @Nefsen402 pointed this is likely an issue on the client side. Changing sway to accommodate Factorio is not an option as it will do more harm than good.

zDEFz commented 6 months ago

Apparently, in i3 this is not an issue. Since sway is i3-compatible

The configuration is compatible, i3 and Sway are using 2 different window protocol (X11 and Wayland respectively).

Wayland defines a protocol that both server and client must respect. As @Nefsen402 pointed this is likely an issue on the client side. Changing sway to accommodate Factorio is not an option as it will do more harm than good.

Thanks for clarifying. What I was getting at, is that if Factorio makes a change, the other implementations of the Wayland Protocol may need to do changes, too. The question is if such a change might be favorable for Factorio, as it potentially is a conflict of interest between different Wayland implementers.

In my opinion: If there is a commonly used standard for this specific implementation, OP should reach out to the Factorio Devs.

emersion commented 6 months ago

The bug is likely in SDL rather than in Factorio itself I think?

GalaxySnail commented 6 months ago

SDL should wait for last configure to complete before resizing again. This is what most applications do.

Sorry if my question is silly. How does a client know which one is the last xdg_surface.configure?

raiguard commented 6 months ago

I have yet to reproduce this issue in my SDL test application but I will keep building it out until I do. There's another strange quirk to this behavior: it only happens on integer display scales. If I swaymsg output DP-2 scale 1.1 and restart the game, the resizing jitters go away and everything becomes perfectly smooth.

OP should reach out to the Factorio Devs

I am a Factorio dev and I am trying to fix this problem. My research led me to this issue because I haven't found a lead in our codebase as to why this is happening yet.

zDEFz commented 6 months ago

I have yet to reproduce this issue in my SDL test application but I will keep building it out until I do. There's another strange quirk to this behavior: it only happens on integer display scales. If I swaymsg output DP-2 scale 1.1 and restart the game, the resizing jitters go away and everything becomes perfectly smooth.

OP should reach out to the Factorio Devs

I am a Factorio dev and I am trying to fix this problem. My research led me to this issue because I haven't found a lead in our codebase as to why this is happening yet.

Thank you for the clarification. This situation closely resembles an issue encountered with wofi in sway, where the width and height were initially calculated automatically but then promptly rearranged due to miscalculations regarding the screen's midpoint.

If you're operating at a scale of 1.1, it's plausible that within this range, the resizing of either width or height might not be reapplied as intended. However, this is merely speculative, based on a past issue (https://github.com/swaywm/sway/issues/7153#issuecomment-1750683211), which was ultimately deemed unrelated to sway.

awsdert commented 4 months ago

Just learned of this issue while watching a broodie yt vid. Came here to give my stop gap fix suggestion (pseudo code - adapt to your code):

static w = 1024;
static h = 720;
static update_at = 0;
static needs_update = false;
resize( width, height )
  update_at = time() + (SECONDS * 3)
  w = width;
  h = height;
  needs_update = true;
end
...
while ( gfxloop )
   if ( needs_update && time() > update_at )
      ...;
   ...
raiguard commented 4 months ago

Yes, I am aware of what needs to happen, I simply haven't figured out why that's not already happening in our ~50,000 lines of graphics code.

awsdert commented 4 months ago

I meant a manual delay as a short term fix for sway builds, not the long term one that requires you to look through that code.