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
This commit is contained in:
Daniel van Vugt 2020-07-01 18:09:14 +08:00 committed by Robert Mader
parent 30d9d1968c
commit ecaaccb064

View File

@ -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;