From 77006e55652c9e2777ad51755cea30e3ed6142a8 Mon Sep 17 00:00:00 2001 From: David Turner Date: Tue, 30 Apr 2024 13:54:56 +0100 Subject: [PATCH] render/pixman: half-pixel shift to match GPUs Add a half-pixel shift in the pixman renderer to match the results given by GPU-based renderers when scaling. --- render/pixman/pass.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/render/pixman/pass.c b/render/pixman/pass.c index 24b8a1b9..ccd629ed 100644 --- a/render/pixman/pass.c +++ b/render/pixman/pass.c @@ -155,6 +155,13 @@ static void render_pass_add_texture(struct wlr_render_pass *wlr_pass, pixman_transform_translate(&transform, NULL, pixman_int_to_fixed(src_box.x), pixman_int_to_fixed(src_box.y)); + // GPUs have a half pixel shift compared to pixman because GPU coordinates refer + // to the centre of each pixel rather than its top-left. This makes no difference + // when there's no transforms as we still copy the correct pixel across. But when + // we do scaling it does make a visible difference, so account for it here. + pixman_transform_translate(&transform, NULL, + -pixman_double_to_fixed(0.5), -pixman_double_to_fixed(0.5)); + pixman_image_set_transform(texture->image, &transform); switch (options->filter_mode) {