4 ms·
I think it’s a fair philosophical choice. Fractional scaling is really hard. macOS doesn’t bother, choosing instead to render at an integer scale factor and dow
by jchw 6y ago
I think it’s a fair philosophical choice. Fractional scaling is really hard. macOS doesn’t bother, choosing instead to render at an integer scale factor and downsample. Doing something similar on Linux would be hard, for mostly historical reasons.
At first blush, it felt like a copout to have the compositor downsample. After all, wouldn’t that be blurry? Then it occurred to me: it’s always going to be blurry. You can’t draw a “1px border” at 150% without blurry edges. I am fully aware that rendering at a higher resolution then downsampling will produce a different result, but, still, so as long as we are piggybacking off the fact that our layouts are constrained to a pixel grid to make our UIs look nice and sharp, fractional scale will be blurry.
The story only keeps getting worse for fractional scale though. People who have used VSCode on fractional DPI have likely already witnessed a somewhat confounding problem: the terminal is not just blurry, but it is scaled such that it sometimes looks like it is 1px off height or width wise. Because it is. HTML is scalable and DPI independent in part because you are only ever exposed to the virtualized pixels. But on the flip side of that, this means that if you have a canvas somewhere, determining how many actual pixels you need for the buffer is not trivially possible. The grid fitting could be different at different corners of the canvas. This obviously is an example specific to HTML, but similar conundrums should naturally appear any time you have only DPI independent units exposed.
Using floating point can get you into trouble too. I have not personally experienced it but I have seen scaling artifacts in Qt that are apparently spurred on by floating point error. While I don’t know the exact mechanism by which this happens, it’s not too hard to construct a scenario in your head.
All of this adds up to a bleak picture in my opinion. Wayland has a very good implementation of DPI awareness that lets unaware clients fallback by simply doing nothing[1], which is a big step up from X11. In theory, Wayland compositors could try to avoid fractional scaling by picking an integer scale to advertise and downsampling all of the surfaces. But even failing that, at least you could push legacy apps to just see everything at 1x, and get the extra blurry visuals.
Until Wayland is a reasonable successor for all users, though, picking between pushing for Wayland for better fractional scaling over Xorg for better software or hardware support is a tough choice. It may not directly factor into Elementary OS and their decision to not support fractional scaling, but I can only imagine it’s not helping any. There are plenty of problems to solve and improve on in Linux that are a bit more tractable.
And then, after we’ve all finally solved all fractional DPI issues, the world will probably have virtually eliminated displays in consumer devices that look too big at 200% scaling. Of course.
[1]: https://wayland-book.com/surfaces-in-depth/hidpi.html https://wayland-book.com/surfaces-in-depth/hidpi.html
P.S.: I am fully aware I left out details here about font rendering, and some GNOME-powered Wayland issues like their horrid dbus API for cursor size change notifications. It’s already a long enough post that goes into the weeds too much.
- slver 6y ago> I think it’s a fair philosophical choice. Fractional scaling is really hard. macOS doesn’t bother, choosing instead to render at an integer scale factor and downsample. Doing something similar on Linux would be hard, for mostly historical reasons. What macOS does is the cleanest and most correct way to fractionally scale in my book. Why would it be hard on Linux? You just blit the buffer at whatever resolution you want.
- jchw 6y agoIn Wayland this is simple. In Xorg it is not because the X protocol contains no knowledge of what scaling factor your app is rendering at. The server doesn’t know about DPI scaling. You can’t just make things “appear” as if they’re a different scale factor; X apps get real pixel coordinates in their events, directly from the X server. The Wayland compositor is aware of what DPI every surface is in a given frame exactly, and it has a unified protocol to advertise it. What macOS does is not terrible, but downsampling from 2x to 1.5x will look a decent bit worse than say 3x to 1.5x or rendering at actual 1.5x. In theory with today’s Wayland protocol, as far as I know, a surface could set its own DPI to 2x or 3x and get the desired behavior today. However it definitely isn’t free... Because of text rendering. Apple is a very... idealistic company. From the very beginning of their use of anti-aliased vector fonts, it’s clear that they did not want hacks like pixel grid fitting or subpixel anti-aliasing that compromises the integrity of the font or ties the rendering closely to the way it is blitted. The way they made up for this was ultimately by shipping HiDPI displays in most of their devices. That way, the blurry rendering became more palatable. Now don’t get me wrong: I’m not saying it looks unusable at 1.5x or 2x scaled down to 1.5x. It just looks dramatically less crisp than actual 1.5x with subpixel anti-aliasing. But you can’t scale a surface with subpixel anti-aliasing without defeating it because the process of scaling will treat the different subpixels of rendered text as just RGB values. This looks terrible. Even worse is if you are using hinting on top of that - now you are grid fitting to a grid that has no correlation to the actual grid of the display, thus, hinting actually just makes things look worse while compromising the integrity of the outlines. Granted, upscaling 1x has some of these issues and it is passable. Still ugly, but it doesn’t look unusably bad. But it is still quite wrong. Turning off hinting and subpixel AA might seem like the right call, but I don’t think so. For some languages, like East Asian languages, subpixel AA can add visual clarity that makes it much easier to read complex glyphs. While for English it is merely a creature comfort, for some languages it might provide a much needed legibility improvement. All of this is what I was trying to subtly allude to near the end, but oh well :) tl;dr: The X server itself is not aware of window DPI, and cannot virtualize pixels in events and protocols. Wayland compositors are, but it is still maturing and software and hardware compatibility is gradually working its way up. And OSes other than macOS use tricks like hinting and subpixel AA to improve font legibility which do not play terribly well with framebuffer scaling. Tl;still dr: doing this would be hard for historical reasons :)