Honestly I'd love it if Linux just implemented a solution similar to what Apple does, which is rendering everything at 2x and then downscaling it to screen's native resolution. (So my "3008x1692" on a 4K screen is actually rendered at 6016x3384). Modern GPUs are strong enough to do this without breaking a sweat, and the result is very crispy and functional. Fractional scaling could still exist as a fallback for older systems.
This is what GTK used to do. It's less battery efficient for an inherently less crisp option though. It also gets less seemingly crisp after rescale for for the much more common "slightly higher than normal dpi closer to 1080p" type monitors (e.g. the 125% in the article) you don't typically find in Apple setups.
Of course that's why subpixel rendering is all a bit moot on Apple devices. For a long time now they've just toggled the default font rendering to the equivalent of "none none" in this article and relying on the high quality screens the devices ship with/most users will plug in to make up for it.
That's what GTK used to do. The result looks much worse than fractional scaling, is much less crisp, uses a lot more battery, and means games run a lot slower.
It is much more crispy for general graphics, with much less problem handling rounding errors and getting lost in antialiasing and fractions that you don't have a place to put into, since hardware does that for you globally for the entire framebuffer. It uses the same amount of battery power when done right (i.e. not using GPU, like GTK did, but the output encoder, like Apple does) and for games, compositors nowadays support overlays with exact virtual resolution and scaling, as the game needs.
How is it much more crispy? If every widget supports fractional DPI correctly, the output will be bit-for-bit identical between the two different approaches.
That said, the GPU and output encoder options chosen by Gtk3 and Apple have a major flaw: accelerated scaling is usually only available in sRGB colorspace, so you get either gamma-incorrect scaling or you need to fall back to a non-accelerated codepath.
> If every widget supports fractional DPI correctly
That is a big if.
> the output will be bit-for-bit identical between the two different approaches.
It won't be identical. When you do it on widget-by-widget basis, you eventually reach the end of your surface, so you may need to paint your antialiased pixels, but the space is beyond your surface.
When the framebuffer is being considered as one global surface, the scaler will do the antialiasing for you outside of your surface, so you won't hit this problem.
Another thing is Apple scales; they limit the error caused by the antialiasing to a group of pixels, either 8x8 or 9x9. The error caused by fractional scaling won't spread outside of this group.
But for the sake of argument, let's say that these errors are not noticable and we can ignore them.
> the GPU and output encoder options chosen by Gtk3 and Apple have a major flaw: accelerated scaling is usually only available in sRGB colorspace, so you get either gamma-incorrect scaling or you need to fall back to a non-accelerated codepath.
This could be output encoder specific; I'm not aware of such limitation, so I'm looking into Intel docs now (TGL ones, volume 12: Display Engine), cannot find any mention of it. Would you have any pointers?
Or do you mean specifically GPU (texture) scaling? I'm not that familiar with GPU part, but I would be surprised if that was true, when the hardware today considers LUTs for the buffers.
For older hardware, or for ARM SBCs, that could be very well true.
---
In the end, both approaches have their pros and cons: with the encoder scaling, you won't be ever pixel-perfect in fractional scales, just good enough; but with software managed fractional scaling, you are over-complicating the already complicated code, so it won't be bug-free, and in the end, might consume more power (and CPU cycles on your CPU!) than the brute-force approach of encoder scaling that is being offloaded to dedicated hardware.
> This could be output encoder specific; I'm not aware of such limitation, so I'm looking into Intel docs now (TGL ones, volume 12: Display Engine), cannot find any mention of it. Would you have any pointers?
> Or do you mean specifically GPU (texture) scaling? I'm not that familiar with GPU part, but I would be surprised if that was true, when the hardware today considers LUTs for the buffers.
To scale in linear RGB colorspace, you first need to do a colorspace transform on the entire buffer, then scale, then do another colorspace transform. I can't find any device that does this in a single step correctly, except for some rare GPU extensions.
> Plane scaling is [sic] supports both linear and non-linear scaling modes. The scaling mode is programmed in the PS_CTRL. In HDR mode, scaling and blending operations are generally performed in linear mode.
To be limited to sRGB would mean, that the hardware is pretty much limited to SDR. That would make it unusable in mainstream market today; just good enough for low-end SBCs.