Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nearest/smart scale_filter flickering back and forth linear/nearest #4798

Closed
luispabon opened this issue Dec 10, 2019 · 15 comments · Fixed by #4903
Closed

Nearest/smart scale_filter flickering back and forth linear/nearest #4798

luispabon opened this issue Dec 10, 2019 · 15 comments · Fixed by #4903
Labels
bug Not working as intended
Milestone

Comments

@luispabon
Copy link

  • Sway Version:
    sway: ad189d2
    wlroots: 8681e4ab8a2d4c95abd34abf0e0eed3351d11bf0

  • Debug Log:
    n/a

  • Configuration File:

sway output eDP-1 pos 0 0 res 3840x2160 scale_filter nearest
  • What happened

I've been testing out the recent work to xwayland scaling filters (#4727) for the last couple of weeks.

I have found one issue. Scenario:

  • sway output eDP-1 pos 0 0 res 3840x2160 scale_filter nearest, also happens with smart)
  • Open two xwayland apps side by side (for some reason it won't work if the other app is wayland native). It seems to happen more when two apps are side by side, not just one

When you click on app A (for instance pycharm), you can see app B changing its scaling from nearest to linear. Causes a very noticeable flickering. Sometimes it's only portions of that window that will go blurry, sometimes it's the whole screen. On Pycharm, you sometimes it's the currently selected line in unison with the cursor blinking.

It's impossible to screenshot. I'll look for a way to record a vid of it.

Before running this new feature, I had simply patched wlroots to always use nearest. As I understand, this patch works in conjunction with https://github.com/swaywm/wlroots/pull/1914/files (which is the line I was patching to use NEAREST) in the understanding that the default is linear anyway. When I patched that line (eg was always set explicitly) there was no flickering at any point.

  • Stack Trace, if sway crashes:
    n/a
@emersion
Copy link
Member

Maybe we're missing a call to set_scale_filter prior to render_texture. To fix this, I'd prefer to move the set_scale_filter call from inside render_texture so that we're sure not to miss new calls.

@luispabon
Copy link
Author

https://www.youtube.com/watch?v=CBKAGahU8yw&feature=youtu.be --> make sure you're viewing the 4k stream on a 4k display, the flickering is a much harder to see at 1080p or less.

@luispabon
Copy link
Author

@emersion do you mean calling set_scale_filter from render_texture? I tried it here and that didn't do it: 39a2e39

@tokyovigilante
Copy link
Contributor

Can 100% confirm this with two tiled Xwayland windows. Does not occur with just forcing GL_NEAREST in wlroots.

@rpigott
Copy link
Member

rpigott commented Dec 13, 2019

Hey guys. I've borrowed some 4k hardware and been working on this for a bit but no solution yet. I'm using xterm as a test client. Using scale_filter nearest here's what I've observed:

  1. I can't reproduce with only one xwayland client on screen.
  2. If there is more than one xwayland client on screen, switching focus between two xwayland clients has a chance to give either the new or the old client "the badness".
  3. Clients with "the badness" appear to alternate between linear and nearest on render. When left alone, for example, "the badness" xterm will alternate between linear and nearest every 5 seconds: whenever my swaybar updates/renders. When the cursor is moved (anywhere) on the output, "the badness" client will flicker very quickly as the cursor is rapidly redrawn.
  4. It appears only one client can have "the badness" at a time. When a new client catches "the badness", the old one is cured.
  5. Switching focus to a wayland client cures "the badness"
  6. It is possible for the badness to affect only a portion of a client. After some testing, I have a hypothesis: parts of the client which are damaged after catching "the badness" are cured. e.g. while echo Hello, world! in a loop I can intentionally give my xterm "the badness" by shifting focus back and forth. When it catches "the badness", I can shake the cursor on the output and observe that only the "Hello world"s above the line it was on when catching "the badness" flicker. When "Hello world"s fill all lines and xterm scrolls to accommodate, "the badness" is cured.
  7. Using swaymsg to switch between scale_filter linear and nearest can cause several clients to catch the badness at once. For clients that catch "the badness" upon switching to scale_filter linear, after "the badness" is cured by any of the above methods they do not flicker and do not catch "the badness" again.

I'm still not terribly familiar with wlroots & gles. If these observations seem interesting to you let me know and maybe I can figure out where to look.

@vesim987
Copy link

vesim987 commented Dec 14, 2019

@emersion do you mean calling set_scale_filter from render_texture? I tried it here and that didn't do it: 39a2e39

This patch fixed the issue for me. Why this commit is not available in the commit tree anymore?

Edit: nvm, it doesn't fully fixed the issue, when I have two xwayland windows opened then the unfocused one is flickering.

@luispabon
Copy link
Author

I realised as I was writing it that the patch wouldn't actually change anything, render_texture is called in 4 places, the two that were missing set_scale_filter were on things that don't require pixel scaling (window borders fi). Looks like something outside sway is resetting the filter to its linear default?

@emersion emersion added the bug Not working as intended label Dec 20, 2019
@emersion emersion added this to the 1.3 milestone Dec 20, 2019
@emersion
Copy link
Member

Logging the scale filter via glGetTexParam right before rendering in wlroots might help debugging this issue.

@rpigott
Copy link
Member

rpigott commented Dec 31, 2019

Sounds good. I'll give it a shot.

@rpigott
Copy link
Member

rpigott commented Jan 1, 2020

Logging works, thanks for the direction. Still don't know where the error is, but I think I've observed it in log form:

# Focused xterm has badness ?
2019-12-31 16:37:15 - [sway/desktop/render.c:237] Rendering toplevel: xterm (focused)
2019-12-31 16:37:15 - [sway/desktop/render.c:91] Set scale_filter GL_NEAREST
2019-12-31 16:37:15 - [render/gles2/renderer.c:159] GL_TEXTURE_MAG_FILTER: GL_LINEAR
2019-12-31 16:37:15 - [sway/desktop/render.c:237] Rendering toplevel: xterm (unfocused)
2019-12-31 16:37:15 - [sway/desktop/render.c:91] Set scale_filter GL_NEAREST
2019-12-31 16:37:15 - [render/gles2/renderer.c:159] GL_TEXTURE_MAG_FILTER: GL_NEAREST

# Unfocused xterm has badness ?
2019-12-31 16:37:24 - [sway/desktop/render.c:237] Rendering toplevel: xterm (unfocused)
2019-12-31 16:37:24 - [sway/desktop/render.c:91] Set scale_filter GL_NEAREST
2019-12-31 16:37:24 - [render/gles2/renderer.c:159] GL_TEXTURE_MAG_FILTER: GL_LINEAR
2019-12-31 16:37:24 - [sway/desktop/render.c:237] Rendering toplevel: xterm (focused)
2019-12-31 16:37:24 - [sway/desktop/render.c:91] Set scale_filter GL_NEAREST
2019-12-31 16:37:24 - [render/gles2/renderer.c:159] GL_TEXTURE_MAG_FILTER: GL_NEAREST

So far I've tried logging the toplevel title/focus in render_view_toplevels, the set scale_filter in set_scale_filter and the actual mag filter value right before rendering in wlroots render_texture_with_matrix.

It appears that the scale_filter does not apply sometimes, but I'm not sure why at the moment. I guess I'll throw more logging at it.

@emersion
Copy link
Member

After more investigation, it seems like glBindTexture sometimes resets the scaling filter. It's not easy to understand whether the scaling filter should be set to NEAREST or LINEAR in wlr_render_texture_with_matrix, because this function is called from wlroots itself too (e.g. from the Wayland and DRM backends when rendering the cursor).

swaywm/wlroots#1992 is an attempt at making things more clear when debugging GL texture parameters. I also have a local patch which prints a stack trace when the filter is LINEAR.

emersion added a commit to emersion/sway that referenced this issue Jan 13, 2020
Two changes were made:

- Bind the texture before glTexParameteri
- Set the scaling filter before each wlr_render_texture_with_matrix call

Logging in wlroots allows to check that the scaling filter is properly
set prior to rendering.

Fixes: 6968fb3 ("add scale_filter output config option")
Closes: swaywm#4798
@emersion
Copy link
Member

Can you try #4903?

@luispabon
Copy link
Author

Testing it now.

@luispabon
Copy link
Author

luispabon commented Jan 13, 2020

@emersion as far as I can tell that fixes the issue completely 👌

@rpigott
Copy link
Member

rpigott commented Jan 13, 2020

@emersion Thanks a million for investigating and fixing this! Patch working as intended here!

ddevault pushed a commit that referenced this issue Jan 13, 2020
Two changes were made:

- Bind the texture before glTexParameteri
- Set the scaling filter before each wlr_render_texture_with_matrix call

Logging in wlroots allows to check that the scaling filter is properly
set prior to rendering.

Fixes: 6968fb3 ("add scale_filter output config option")
Closes: #4798
emersion added a commit that referenced this issue Jan 15, 2020
Two changes were made:

- Bind the texture before glTexParameteri
- Set the scaling filter before each wlr_render_texture_with_matrix call

Logging in wlroots allows to check that the scaling filter is properly
set prior to rendering.

Fixes: 6968fb3 ("add scale_filter output config option")
Closes: #4798
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Not working as intended
Development

Successfully merging a pull request may close this issue.

5 participants