From c1a29cba4de6c1b89076e9f08757c614d9565e4f Mon Sep 17 00:00:00 2001 From: jknockel <24300095+jknockel@users.noreply.github.com> Date: Tue, 14 May 2024 15:14:08 -0400 Subject: [PATCH] meta-crtc-xrandr.c: use nearest neighbor filter for integer randr scales (#692) Use the nearest neighbor filter if the scaling factor is an integer. This provides a crisper, less blurry scale when the scale is an integer. Note that this change only affects fractional scaling when the "scale-up" mode is used. Scaling down is unaffected by this change, and non-integer scaling up is also unaffected by this change. This behavior was already in Cinnamon 5.4, but it was lost at some point in between 5.4 and now. Note finally that the "nearest" filter is a filter guaranteed to exist by the RENDER protocol [1]. [1] https://cgit.freedesktop.org/xorg/proto/renderproto/tree/renderproto.txt --- src/backends/x11/meta-crtc-xrandr.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/backends/x11/meta-crtc-xrandr.c b/src/backends/x11/meta-crtc-xrandr.c index 8c875fc5e..e7c1d5854 100644 --- a/src/backends/x11/meta-crtc-xrandr.c +++ b/src/backends/x11/meta-crtc-xrandr.c @@ -135,6 +135,7 @@ meta_crtc_xrandr_set_scale (MetaCrtc *crtc, DOUBLE_TO_FIXED (0), DOUBLE_TO_FIXED (1), DOUBLE_TO_FIXED (0), DOUBLE_TO_FIXED (0), DOUBLE_TO_FIXED (0), DOUBLE_TO_FIXED (1) }; + float integer_scale; if (!(meta_monitor_manager_get_capabilities (monitor_manager) & META_MONITOR_MANAGER_CAPABILITY_NATIVE_OUTPUT_SCALING)) @@ -145,9 +146,19 @@ meta_crtc_xrandr_set_scale (MetaCrtc *crtc, if (fabsf (scale - 1.0f) > 0.001) { - scale_filter = FilterGood; - transformation.matrix11 = DOUBLE_TO_FIXED (1.0 / scale); - transformation.matrix22 = DOUBLE_TO_FIXED (1.0 / scale); + integer_scale = roundf (scale); + if (fabsf (scale - integer_scale) > 0.001) + { + scale_filter = FilterGood; + transformation.matrix11 = DOUBLE_TO_FIXED (1.0 / scale); + transformation.matrix22 = DOUBLE_TO_FIXED (1.0 / scale); + } + else /* if integer multiple then use nearest neighbor filter */ + { + scale_filter = "nearest"; + transformation.matrix11 = DOUBLE_TO_FIXED (1.0 / integer_scale); + transformation.matrix22 = DOUBLE_TO_FIXED (1.0 / integer_scale); + } } else scale_filter = FilterFast;