From ecaaccb0645222064f0035ac729e488f27799ec0 Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Wed, 1 Jul 2020 18:09:14 +0800 Subject: [PATCH] background: Use NEAREST filtering when the texture is the monitor resolution That was obviously always the intention, but it didn't work when the display was scaled. My 3840x2160 monitor with a 3840x2160 texture was being rendered with LINEAR filtering. It seems the `force_bilinear` flag was TRUE when it should be FALSE. Because a texture area that's an integer fraction of the texture resolution is still a perfect match when that integer is the monitor scale. We were also getting: `meta_actor_painting_untransformed (fb, W, H, W, H, NULL, NULL) == FALSE` when the display was scaled. Because the second W,H was not the real sampling resolution. So with both of those issues fixed we now get NEAREST filtering when the texture resolution matches the resolution it's physically being rendered at. Note: The background texture actually wasn't equal to the physical monitor resolution prior to January 2020 (76240e24f7). So it wasn't possible to do this before then. Since then however, the texture resolution is always equal to the physical monitor resolution. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1346 --- src/compositor/meta-background-content.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/compositor/meta-background-content.c b/src/compositor/meta-background-content.c index 1d4188c2b..e3924cae2 100644 --- a/src/compositor/meta-background-content.c +++ b/src/compositor/meta-background-content.c @@ -163,7 +163,7 @@ struct _MetaBackgroundContent CoglPipeline *pipeline; PipelineFlags pipeline_flags; cairo_rectangle_int_t texture_area; - gboolean force_bilinear; + int texture_width, texture_height; cairo_region_t *clip_region; cairo_region_t *unobscured_region; @@ -336,9 +336,17 @@ setup_pipeline (MetaBackgroundContent *self, self->monitor, &self->texture_area, &wrap_mode); - self->force_bilinear = texture && - (self->texture_area.width != (int)cogl_texture_get_width (texture) || - self->texture_area.height != (int)cogl_texture_get_height (texture)); + + if (texture) + { + self->texture_width = cogl_texture_get_width (texture); + self->texture_height = cogl_texture_get_height (texture); + } + else + { + self->texture_width = 0; + self->texture_height = 0; + } cogl_pipeline_set_layer_texture (self->pipeline, 0, texture); cogl_pipeline_set_layer_wrap_mode (self->pipeline, 0, wrap_mode); @@ -401,12 +409,11 @@ setup_pipeline (MetaBackgroundContent *self, opacity / 255.); fb = clutter_paint_context_get_framebuffer (paint_context); - if (!self->force_bilinear && - meta_actor_painting_untransformed (fb, - actor_pixel_rect->width, - actor_pixel_rect->height, + if (meta_actor_painting_untransformed (fb, actor_pixel_rect->width, actor_pixel_rect->height, + self->texture_width, + self->texture_height, NULL, NULL)) { min_filter = COGL_PIPELINE_FILTER_NEAREST;