diff -Nru mutter-3.28.2/debian/changelog mutter-3.28.2/debian/changelog --- mutter-3.28.2/debian/changelog 2018-05-20 22:21:35.000000000 +0800 +++ mutter-3.28.2/debian/changelog 2018-06-07 13:51:42.000000000 +0800 @@ -1,3 +1,14 @@ +mutter (3.28.2-2ubuntu1) cosmic; urgency=medium + + * Add lp1767648-clutter-Fix-offscreen-effect-painting-of-clones.patch to + fix clipped gnome-shell panel and menus when in zoom mode. (LP: #1767648) + * Add shaped-texture-Disable-mipmapping-during-animation.patch to improve + gnome-shell rendering performance. + * Add clutter-actor-Fix-uninitialized-matrix-multiply.patch to avoid + undefined behaviour arising from uninitialized memory. + + -- Daniel van Vugt Thu, 07 Jun 2018 13:51:42 +0800 + mutter (3.28.2-2) unstable; urgency=medium * Team upload diff -Nru mutter-3.28.2/debian/patches/clutter-actor-Fix-uninitialized-matrix-multiply.patch mutter-3.28.2/debian/patches/clutter-actor-Fix-uninitialized-matrix-multiply.patch --- mutter-3.28.2/debian/patches/clutter-actor-Fix-uninitialized-matrix-multiply.patch 1970-01-01 08:00:00.000000000 +0800 +++ mutter-3.28.2/debian/patches/clutter-actor-Fix-uninitialized-matrix-multiply.patch 2018-06-07 13:49:45.000000000 +0800 @@ -0,0 +1,27 @@ +Description: clutter-actor: Fix uninitialized matrix multiply + `modelview` is uninitialized and the `apply` function just multiplies it. + What we really want is to initialize `modelview` so replace `apply` with + `get`. + . + Who knows what bugs this may have caused... +Author: Daniel van Vugt +Origin: upstream, https://gitlab.gnome.org/GNOME/mutter/commit/62c67be4c8 +Forwarded: yes +Last-Update: 2018-06-07 + +diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c +index 6954f0396..3e00a11db 100644 +--- a/clutter/clutter/clutter-actor.c ++++ b/clutter/clutter/clutter-actor.c +@@ -2821,7 +2821,7 @@ _clutter_actor_fully_transform_vertices (ClutterActor *self, + /* Note: we pass NULL as the ancestor because we don't just want the modelview + * that gets us to stage coordinates, we want to go all the way to eye + * coordinates */ +- _clutter_actor_apply_relative_transformation_matrix (self, NULL, &modelview); ++ _clutter_actor_get_relative_transformation_matrix (self, NULL, &modelview); + + /* Fetch the projection and viewport */ + _clutter_stage_get_projection_matrix (CLUTTER_STAGE (stage), &projection); +-- +2.17.0 + diff -Nru mutter-3.28.2/debian/patches/lp1767648-clutter-Fix-offscreen-effect-painting-of-clones.patch mutter-3.28.2/debian/patches/lp1767648-clutter-Fix-offscreen-effect-painting-of-clones.patch --- mutter-3.28.2/debian/patches/lp1767648-clutter-Fix-offscreen-effect-painting-of-clones.patch 1970-01-01 08:00:00.000000000 +0800 +++ mutter-3.28.2/debian/patches/lp1767648-clutter-Fix-offscreen-effect-painting-of-clones.patch 2018-06-07 13:46:54.000000000 +0800 @@ -0,0 +1,131 @@ +Description: clutter: Fix offscreen-effect painting of clones + `ClutterOffscreenEffect` had been getting the wrong bounding box in the + case of clones and descendents of clones. This was due to + `clutter_actor_get_paint_box` only considering the transformation of the + source actor rather than the clone. + . + Even if we weren't painting a clone, but an offscreened descendent of a + clone (like in gnome-shell's desktop zoom), we would get the wrong + transformation from `clutter_actor_get_paint_box` and thus also calculate + the clipping viewport incorrectly. + . + Fortunately we don't need to know the actual clone/actor being painted. + What we do know is that we are painting an actor (or clone thereof) with + a transformation that's already been set in cogl for us by + `clutter_actor_paint`. That is definitely the correct transformation to + use. So `pre_paint` has been modified to only keep untransformed rendering + in the FBO and `paint_texture` modified to account for it and use the + correct transformation of the current paint chain. + . + Special thanks to Mai Lavelle for identifying the cause of the problem. +Author: Daniel van Vugt +Bug: https://bugzilla.gnome.org/show_bug.cgi?id=789050 +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1767648 +Origin: https://gitlab.gnome.org/GNOME/mutter/merge_requests/117 +Forwarded: yes +Last-Update: 2018-06-07 + +diff --git a/clutter/clutter/clutter-offscreen-effect.c b/clutter/clutter/clutter-offscreen-effect.c +index 1dbf29f60..057898f92 100644 +--- a/clutter/clutter/clutter-offscreen-effect.c ++++ b/clutter/clutter/clutter-offscreen-effect.c +@@ -74,6 +74,7 @@ + #include "clutter-debug.h" + #include "clutter-private.h" + #include "clutter-stage-private.h" ++#include "clutter-paint-volume-private.h" + + struct _ClutterOffscreenEffectPrivate + { +@@ -223,7 +224,8 @@ clutter_offscreen_effect_pre_paint (ClutterEffect *effect) + ClutterOffscreenEffectPrivate *priv = self->priv; + ClutterActorBox box; + ClutterActor *stage; +- CoglMatrix projection; ++ CoglMatrix projection, modelview; ++ const ClutterPaintVolume *volume; + CoglColor transparent; + gfloat stage_width, stage_height; + gfloat fbo_width = -1, fbo_height = -1; +@@ -240,24 +242,32 @@ clutter_offscreen_effect_pre_paint (ClutterEffect *effect) + stage = _clutter_actor_get_stage_internal (priv->actor); + clutter_actor_get_size (stage, &stage_width, &stage_height); + +- /* The paint box is the bounding box of the actor's paint volume in +- * stage coordinates. This will give us the size for the framebuffer +- * we need to redirect its rendering offscreen and its position will +- * be used to setup an offset viewport */ +- if (clutter_actor_get_paint_box (priv->actor, &box)) ++ /* Get the minimal bounding box for what we want to paint, relative to the ++ * parent of priv->actor. Note that we may actually be painting a clone of ++ * priv->actor so we need to be careful to avoid querying the transformation ++ * of priv->actor (like clutter_actor_get_paint_box would). Just stay in ++ * local coordinates for now... ++ */ ++ volume = clutter_actor_get_paint_volume (priv->actor); ++ if (volume) + { +- clutter_actor_box_get_size (&box, &fbo_width, &fbo_height); +- clutter_actor_box_get_origin (&box, &priv->x_offset, &priv->y_offset); ++ ClutterPaintVolume mutable_volume; + +- fbo_width = MIN (fbo_width, stage_width); +- fbo_height = MIN (fbo_height, stage_height); ++ _clutter_paint_volume_copy_static (volume, &mutable_volume); ++ _clutter_paint_volume_get_bounding_box (&mutable_volume, &box); ++ clutter_paint_volume_free (&mutable_volume); + } + else + { +- fbo_width = stage_width; +- fbo_height = stage_height; ++ clutter_actor_get_allocation_box (priv->actor, &box); + } + ++ clutter_actor_box_get_size (&box, &fbo_width, &fbo_height); ++ clutter_actor_box_get_origin (&box, &priv->x_offset, &priv->y_offset); ++ ++ fbo_width = MIN (fbo_width, stage_width); ++ fbo_height = MIN (fbo_height, stage_height); ++ + if (fbo_width == stage_width) + priv->x_offset = 0.0f; + if (fbo_height == stage_height) +@@ -279,8 +289,14 @@ clutter_offscreen_effect_pre_paint (ClutterEffect *effect) + /* let's draw offscreen */ + cogl_push_framebuffer (priv->offscreen); + +- /* Copy the modelview that would have been used if rendering onscreen */ +- cogl_set_modelview_matrix (&priv->last_matrix_drawn); ++ /* We don't want the FBO contents to be transformed. That could waste memory ++ * (e.g. during zoom), or result in something that's not rectangular (clipped ++ * incorrectly). So drop the modelview matrix of the current paint chain. ++ * This is fine since paint_texture now runs with the same modelview matrix, ++ * so it will come out correctly... ++ */ ++ clutter_actor_get_transform (priv->stage, &modelview); ++ cogl_set_modelview_matrix (&modelview); + + /* Set up the viewport so that it has the same size as the stage, + * but offset it so that the actor of interest lands on our +@@ -382,12 +398,12 @@ clutter_offscreen_effect_paint_texture (ClutterOffscreenEffect *effect) + + cogl_push_matrix (); + +- /* Now reset the modelview to put us in stage coordinates so +- * we can drawn the result of our offscreen render as a textured +- * quad... */ ++ cogl_get_modelview_matrix (&modelview); + +- cogl_matrix_init_identity (&modelview); +- _clutter_actor_apply_modelview_transform (priv->stage, &modelview); ++ /* Our FBO has been shrunken smaller than the stage to save on memory and ++ * just contains the actor of interest. So to avoid it landing at the ++ * top-left corner of the screen, restore its correct location: ++ */ + cogl_matrix_translate (&modelview, priv->x_offset, priv->y_offset, 0.0f); + cogl_set_modelview_matrix (&modelview); + +-- +2.17.0 + diff -Nru mutter-3.28.2/debian/patches/series mutter-3.28.2/debian/patches/series --- mutter-3.28.2/debian/patches/series 2018-05-20 22:21:35.000000000 +0800 +++ mutter-3.28.2/debian/patches/series 2018-06-07 13:47:17.000000000 +0800 @@ -11,3 +11,6 @@ debian/synaptics-support.patch debian/skip-failing-tests.patch debian/skip-failing-tests-325.patch +lp1767648-clutter-Fix-offscreen-effect-painting-of-clones.patch +shaped-texture-Disable-mipmapping-during-animation.patch +clutter-actor-Fix-uninitialized-matrix-multiply.patch diff -Nru mutter-3.28.2/debian/patches/shaped-texture-Disable-mipmapping-during-animation.patch mutter-3.28.2/debian/patches/shaped-texture-Disable-mipmapping-during-animation.patch --- mutter-3.28.2/debian/patches/shaped-texture-Disable-mipmapping-during-animation.patch 1970-01-01 08:00:00.000000000 +0800 +++ mutter-3.28.2/debian/patches/shaped-texture-Disable-mipmapping-during-animation.patch 2018-06-07 13:45:56.000000000 +0800 @@ -0,0 +1,160 @@ +Description: shaped-texture: Disable mipmapping during animation + This avoids overwhelming the GPU with trying to update mipmaps at a high + rate. Because doing so could easily cause a reduction in the compositor + frame rate and thus actually reduce visual quality. + . + In the case of a window that is constantly animating in the overview, + this reduces mutter's render time by around 20%-30%. +Author: Daniel van Vugt +Origin: upstream, https://gitlab.gnome.org/GNOME/mutter/commit/c9c3283540 +Forwarded: yes +Last-Update: 2018-06-07 + +diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c +index 98346c6ae..0240c067c 100644 +--- a/src/compositor/meta-shaped-texture.c ++++ b/src/compositor/meta-shaped-texture.c +@@ -38,6 +38,20 @@ + + #include "meta-cullable.h" + ++/* MAX_MIPMAPPING_FPS needs to be as small as possible for the best GPU ++ * performance, but higher than the refresh rate of commonly slow updating ++ * windows like top or a blinking cursor, so that such windows do get ++ * mipmapped. ++ */ ++#define MAX_MIPMAPPING_FPS 5 ++#define MIN_MIPMAP_AGE_USEC (G_USEC_PER_SEC / MAX_MIPMAPPING_FPS) ++ ++/* MIN_FAST_UPDATES_BEFORE_UNMIPMAP allows windows to update themselves ++ * occasionally without causing mipmapping to be disabled, so long as such ++ * an update takes fewer update_area calls than: ++ */ ++#define MIN_FAST_UPDATES_BEFORE_UNMIPMAP 20 ++ + static void meta_shaped_texture_dispose (GObject *object); + + static void meta_shaped_texture_paint (ClutterActor *actor); +@@ -95,6 +109,11 @@ struct _MetaShapedTexturePrivate + guint tex_width, tex_height; + guint fallback_width, fallback_height; + ++ gint64 prev_invalidation, last_invalidation; ++ guint fast_updates; ++ guint remipmap_timeout_id; ++ gint64 earliest_remipmap; ++ + guint create_mipmaps : 1; + }; + +@@ -191,6 +210,12 @@ meta_shaped_texture_dispose (GObject *object) + MetaShapedTexture *self = (MetaShapedTexture *) object; + MetaShapedTexturePrivate *priv = self->priv; + ++ if (priv->remipmap_timeout_id) ++ { ++ g_source_remove (priv->remipmap_timeout_id); ++ priv->remipmap_timeout_id = 0; ++ } ++ + if (priv->paint_tower) + meta_texture_tower_free (priv->paint_tower); + priv->paint_tower = NULL; +@@ -372,6 +397,21 @@ set_cogl_texture (MetaShapedTexture *stex, + meta_texture_tower_set_base_texture (priv->paint_tower, cogl_tex); + } + ++static gboolean ++texture_is_idle_and_not_mipmapped (gpointer user_data) ++{ ++ MetaShapedTexture *stex = META_SHAPED_TEXTURE (user_data); ++ MetaShapedTexturePrivate *priv = stex->priv; ++ ++ if ((g_get_monotonic_time () - priv->earliest_remipmap) < 0) ++ return G_SOURCE_CONTINUE; ++ ++ clutter_actor_queue_redraw (CLUTTER_ACTOR (stex)); ++ priv->remipmap_timeout_id = 0; ++ ++ return G_SOURCE_REMOVE; ++} ++ + static void + meta_shaped_texture_paint (ClutterActor *actor) + { +@@ -381,9 +421,10 @@ meta_shaped_texture_paint (ClutterActor *actor) + guchar opacity; + CoglContext *ctx; + CoglFramebuffer *fb; +- CoglTexture *paint_tex; ++ CoglTexture *paint_tex = NULL; + ClutterActorBox alloc; + CoglPipelineFilter filter; ++ gint64 now = g_get_monotonic_time (); + + if (priv->clip_region && cairo_region_is_empty (priv->clip_region)) + return; +@@ -406,13 +447,34 @@ meta_shaped_texture_paint (ClutterActor *actor) + * Setting the texture quality to high without SGIS_generate_mipmap + * support for TFP textures will result in fallbacks to XGetImage. + */ +- if (priv->create_mipmaps) +- paint_tex = meta_texture_tower_get_paint_texture (priv->paint_tower); +- else +- paint_tex = COGL_TEXTURE (priv->texture); ++ if (priv->create_mipmaps && priv->last_invalidation) ++ { ++ gint64 age = now - priv->last_invalidation; ++ ++ if (age >= MIN_MIPMAP_AGE_USEC || ++ priv->fast_updates < MIN_FAST_UPDATES_BEFORE_UNMIPMAP) ++ paint_tex = meta_texture_tower_get_paint_texture (priv->paint_tower); ++ } + + if (paint_tex == NULL) +- return; ++ { ++ paint_tex = COGL_TEXTURE (priv->texture); ++ ++ if (paint_tex == NULL) ++ return; ++ ++ if (priv->create_mipmaps) ++ { ++ /* Minus 1000 to ensure we don't fail the age test in timeout */ ++ priv->earliest_remipmap = now + MIN_MIPMAP_AGE_USEC - 1000; ++ ++ if (!priv->remipmap_timeout_id) ++ priv->remipmap_timeout_id = ++ g_timeout_add (MIN_MIPMAP_AGE_USEC / 1000, ++ texture_is_idle_and_not_mipmapped, ++ stex); ++ } ++ } + + tex_width = priv->tex_width; + tex_height = priv->tex_height; +@@ -758,6 +820,20 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, + + meta_texture_tower_update_area (priv->paint_tower, x, y, width, height); + ++ priv->prev_invalidation = priv->last_invalidation; ++ priv->last_invalidation = g_get_monotonic_time (); ++ ++ if (priv->prev_invalidation) ++ { ++ gint64 interval = priv->last_invalidation - priv->prev_invalidation; ++ gboolean fast_update = interval < MIN_MIPMAP_AGE_USEC; ++ ++ if (!fast_update) ++ priv->fast_updates = 0; ++ else if (priv->fast_updates < MIN_FAST_UPDATES_BEFORE_UNMIPMAP) ++ priv->fast_updates++; ++ } ++ + unobscured_region = effective_unobscured_region (stex); + if (unobscured_region) + { +-- +2.17.0 +