diff options
author | Marco Trevisan (TreviƱo) <mail@3v1n0.net> | 2018-11-22 08:13:43 +0100 |
---|---|---|
committer | Marco Trevisan <mail@3v1n0.net> | 2019-03-01 17:46:49 +0000 |
commit | 1e1cb4961baec755ece844d53d2f7122a83453bb (patch) | |
tree | 24fbefc88dd3f00d8332ba2971bad3ccd45a183c | |
parent | e3966882e8a125d66b0222601922f5c0a77c792c (diff) | |
download | mutter-1e1cb4961baec755ece844d53d2f7122a83453bb.tar.gz |
clutter/offscreen-effect: Make sure we use linear filter for fractional scaling
When we try to update the FB, we might face the case in which the effect target
framebuffer does not need any redraw, because it's already properly sized and
scaled, but the filter applied to the pipeline is not, because it has been
computed for a non-fractional scaling.
This is happens for example to clutter actors with a flattening effect (i.e.
override redirect mode set), that might have been generated properly for a
celied scaling level, but when we go fractional we need to ensure to use a
linear filter, as the 1:1 texel:pixel assumption is not true anymore.
https://bugzilla.gnome.org/show_bug.cgi?id=765011
https://gitlab.gnome.org/GNOME/mutter/merge_requests/3
-rw-r--r-- | clutter/clutter/clutter-offscreen-effect.c | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/clutter/clutter/clutter-offscreen-effect.c b/clutter/clutter/clutter-offscreen-effect.c index ad338a935..cb554f44c 100644 --- a/clutter/clutter/clutter-offscreen-effect.c +++ b/clutter/clutter/clutter-offscreen-effect.c @@ -137,6 +137,30 @@ clutter_offscreen_effect_real_create_texture (ClutterOffscreenEffect *effect, COGL_PIXEL_FORMAT_RGBA_8888_PRE); } +static void +ensure_pipeline_filter_for_scale (ClutterOffscreenEffect *self, + float resource_scale) +{ + CoglPipelineFilter filter; + + if (!self->priv->target) + return; + + /* If no fractional scaling is set, we're always going to render the texture + at a 1:1 texel:pixel ratio so, in such case we can use 'nearest' filtering + to decrease the effects of rounding errors in the geometry calculation; + if instead we we're using a global fractional scaling we need to make sure + that we're using the default linear effect, not to create artifacts when + scaling down the texture */ + if (fmodf (resource_scale, 1.0f) == 0) + filter = COGL_PIPELINE_FILTER_NEAREST; + else + filter = COGL_PIPELINE_FILTER_LINEAR; + + cogl_pipeline_set_layer_filters (self->priv->target, 0 /* layer_index */, + filter, filter); +} + static gboolean update_fbo (ClutterEffect *effect, int target_width, @@ -159,7 +183,10 @@ update_fbo (ClutterEffect *effect, if (priv->target_width == target_width && priv->target_height == target_height && priv->offscreen != NULL) + { + ensure_pipeline_filter_for_scale (self, resource_scale); return TRUE; + } if (priv->target == NULL) { @@ -167,17 +194,7 @@ update_fbo (ClutterEffect *effect, clutter_backend_get_cogl_context (clutter_get_default_backend ()); priv->target = cogl_pipeline_new (ctx); - - if (fmodf (resource_scale, 1.0f) == 0) - { - /* We're always going to render the texture at a 1:1 texel:pixel - ratio so we can use 'nearest' filtering to decrease the - effects of rounding errors in the geometry calculation */ - cogl_pipeline_set_layer_filters (priv->target, - 0, /* layer_index */ - COGL_PIPELINE_FILTER_NEAREST, - COGL_PIPELINE_FILTER_NEAREST); - } + ensure_pipeline_filter_for_scale (self, resource_scale); } if (priv->texture != NULL) |