Everything is blurrier with fractional scaling (Wayland-native, not Xwayland)
Describe the bug When using fractional scaling, all fonts and images that have to be upscaled or downscaled are blurrier than what they would be when using 1x or 2x scaling (or using x11). This happens everywhere, from my panel to browser to code editor, etc.
I require 1.75x scaling because of the very high DPI of my screen but then the blurryness caused by it, while not incapacitating, makes it harder to read as if i had slight vision loss.
Steps To Reproduce
- Set scaling to 1x or 2x and view the sharp fonts and images
- Set scaling to a fractional value like 1.75 or 1.99 and notice the difference
Expected behavior Fonts and images should remain as sharp as they would on integer scaling
Screenshots or stacktrace
2x scaling:
1.99x scaling:
2x scaling:
1.99x scaling:
While I used 1.99x to examplify, this problem happens on any scaling that isnt an integer value.
Wayfire version 0.9.0
I saw other closed issues related to fractional scaling and blurryness but they seemed to be a different kind of problem, mostly related with Firefox. In my case this problem occurs on all applications and so I opened this issue
fractiona scaling is blurry by nature. What this shit does - is simply take a fully rendered picture and scale it a s an image. If you scale image (f.e. with GIMP) - it will be blurry. Of course it depends on initial image quality - if it is hi-dpi already you will not notice it. But if image quality is bad - and you scle it to look bigger - you get what you get.
The physics of this is simple - if you have х2 ratio - that means tha 1 pixel wil become square of 2х2 pixels so thw thinks that were sharp - will remain sharp. Sharpness is mde by getting your fonts as close as possible to the pixel matrix. That's why in old times with bad resolutions so called bitbap fonts were popular. When the fons were designed not as a vector - but as a matrix of black and white pixels, which allow to have sharp fonts on a terrible displays.
When tou do 1,75 - you can not have the same pixel allignment as you had in original or x2 scle. Now your font border may be not between the pixels - but in the middle of the pixel. And there is no way to have sharp fonts and fractional scale.
If you want sharp fonts - just do not use fractional but adjust font sizes. Fonts will be rendered best way to fit your pixel structure then.
If I adjust only the font size, the rest of the GUI elements will not scale properly, and I will have disproportionally large fonts compared to the rest of the interface.
I understand the concept of mixels, interpolation filters and scaling since I do a lot of image stuff, that's not the problem here. The problem is the fact that wl-roots compositors don't treat fractional scaling as an x11-like DPI setting instead, where fonts and UI elements have their sizes increased before rendering rather than rendering the whole graphical interface at a bigger size to then downscale it. Xfce on X11 already does this with the DPI setting in the fonts page, and Windows looks sharp on fractional scaling because it probably uses this approach as well.
In a summary I mean that fractional scaling is supposed to follow this idea of "ok tell to scale up gui elements and fonts at 1.75x the size before rendering the frame" rather than "ok let's render all of this at 2x, have a final raster frame then downscale it to 1.75x with interpolation"
I set display scaling to 2x then decreased the font sizes (drastically so the effect is more noticeable). Notice how the GUI elements do not scale down as I scaled down the fonts. Because of this, fractional scaling is a must
This seems to be a problem from wl-roots itself and a fix is being worked on. Once it's merged and a new release is made, it should also fix things on Wayfire and all other compositors.
Note that we don't use wlr-scene so we'll have to adopt the same changes in Wayfire, namely moving everything to double coordinates. But it seems that we'll first have to wait for a new pixman release before we can really do that. Also I am a bit sceptical that this change will solve all bluriness issues with fractional scaling ... But let's hope it does work :)
Мy point here is - the blurry effect is a nature of a fractional scaling. Pixels on the screen are quantum objects - they are integers, and they can scale to any crazy factor. In quantum world you can not have 1.99 photons emitted. You can have 1 or 2 or 3. But never 1.99 or even 1.5.
Same way heere - you can light 1 pixel or 2 pixels. You can not light 1.99 pixels , intead ot that you light 2 pixels with 1.99 brightness - and that's what give you blurriness. All the efforts here are absolute waste unless you have very high resolution object. If your line is 1 pixel wide - you will be blurry no matter what you do. If yur line is 200 pixels wide - then fractional will work.
That's math and physics - you cannot do anything within here, well maybe you can cheat - say well 1.99 -ok, I will do it 2 then. silently - and wil be sharper image. Its roughly speaking of course - but we can take typical font line width and somehow calculate rounding factor. But doubling the precision will just eat your battery for nothing - because blurriness is not coming from the presicion of the caclulation but because of the nature of the display matrix. And the way to minimize the blurriness here will depend on matrix model and pixel allignment - same way as subpixel rendering hints are used to scale fonts. And here we have issue again as our initial picture is already subpixel-alligned so it looks sharper - but if you move it half-pixel left or right it will not be sharp anymore. And then you scale - so even more trouble, because initial engine was placing the font characters on canvas. while the scaling engine is scaling the whole picture and have no idea if the blue pixel is a real pixel or just a subpixel lighted blue to be part of the pixel next to it. And finally all those efforts will end up to the same blurriness but half of the battery life.
We do have support for fractional scaling which can be pixel perfect but I am not sure how many applications support it. See https://wayland.app/protocols/fractional-scale-v1
That's the different story - here we just send the app information how to paint the window. Like when I set the diplay DPI fe in mate-control-center - apps on my screen adjust by re-rendering the fonts, pixmaps and everything with the new scale factor. And that will be pixel-perfect because we do not render small picture and then scale it as a single bitmap, but we let the app to scale every element. But you right - it depends on every single app - do they do it or not. And that is surely not the case for the apps topicstarter cares about - those apps do not support.that. And with this you can not drag your window from one display to another - app can not dynamically paint part of the window scale 1 and part scale 2 when half window on monitor 1 and part on the monitor 2. While the picture-scaling logic can allow this.
That's the different story - here we just send the app information how to paint the window. Like when I set the diplay DPI fe in mate-control-center - apps on my screen adjust by re-rendering the fonts, pixmaps and everything with the new scale factor. And that will be pixel-perfect because we do not render small picture and then scale it as a single bitmap, but we let the app to scale every element. But you right - it depends on every single app - do they do it or not. And that is surely not the case for the apps topicstarter cares about - those apps do not support.that. And with this you can not drag your window from one display to another - app can not dynamically paint part of the window scale 1 and part scale 2 when half window on monitor 1 and part on the monitor 2. While the picture-scaling logic can allow this.
Well sure I think we will have some blurriness no matter what. I am mostly waiting for the rest of the ecosystem to settle down on some preferred way of doing things and then we'll think about how to implement that in Wayfire.
Just read the article today - see what KDE does. For sure those guys have much more resources than Wayfire team - and even with their powers could not find better solution.
https://share.google/5rEdiOzHHFFQo3eyu
KDE tries to scale everything, including subpixel rendering and font hinting, which leads to issues when the final scaled output doesn't align cleanly with the physical pixel grid. As a result, users may see jagged text and rainbow-colored fringes around glyphs due to improperly scaled subpixel anti-aliasing. This behavior is tracked in KDE bug 499289.
The proper approach is to inform applications about the scaling factor (environment variables or toolkit-specific APIs) and let them render natively at the correct scale. This avoids the blurry or "soapy" appearance that results from upscaling already-rendered content.
GNOME follows this approach, delegating scaling to applications, which allows for crisp rendering and proper subpixel text without distortion.
I’m also experiencing this issue in Wayfire versions 0.8, 0.9, and the latest master branch. I’ve found that rendering becomes sharp under the following conditions: When the window is an overlay (like waybar). Or when the window is fullscreen. Or when an additional monitor with a higher resolution than the one using fractional scaling is connected. Alternatively, creating a headless display with 4K resolution and DPI scale set to 2 also helps.